Trailing-Edge
-
PDP-10 Archives
-
AP-D543V_SB
-
netser.mac
There are 13 other files named netser.mac in the archive. Click here to see a list.
TITLE NETSER - COMMUNICATION DEVICE INDEPENDENT NETWORK SERVICE ROUTINES - V14112
SUBTTL D. TODD/DRT/EJW 28 NOV 78
SEARCH F,S,NETPRM
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1974,1975,1976,1977,1978 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VNETSER,14112 ;PUT VERSION NUMBER IN GLOB AND LOADER MAP
NETSER::ENTRY NETSER ;LOADING IF IN LIBRARY SEARCH MODE
COMMENT\ ;;;REVISION HISTORY
V0 ;INITIAL PRODUCT IMPLEMENTATION
\
EXTERNAL DEVNET
SUBTTL TABLE ON CONTENTS
; TABLE OF CONTENTS FOR NETSER
;
;
; SECTION PAGE
; 1. TABLE OF CONTENTS......................................... 2
; 2. DEVICE DATA BLOCKS........................................ 3
; 3. TSTNET - FIND OUT IF A DEVICE EXISTS ON THE NETWORK....... 5
; 4. INTERFACE TO COMCON FOR THE "NODE" COMMAND................ 8
; 5. INTERFACE TO UUOCON FOR THE NODE UUO...................... 9
; 6. NODE.1 - ASSIGN A REMOTE DEVICE........................... 10
; 7. NODE.2 RETURN A NODE NUMBER IN THE AC................... 11
; 8. NODE.3 STATION CONTOL MESSAGES............................ 12
; 9. NODE.4 AUTO RELOAD OF DOWN LINE DAS80 SERIES STATIONS..... 13
; 10. LOCATE & WHERE COMMAND/UUOS............................... 14
; 11. SCB INTERFACE ROUTINES.................................... 17
; 12. MAKDDB - SURROUTINE TO BUILD A NETDDB..................... 18
; 13. MBF - INTERNAL MONITOR BUFFER ROUTINES.................... 19
; 14. AVOMBF - AVDVNCE AN OUTPUT MONITOR BUFFER................. 20
; 15. MAKPCB - BUILD A PROTOCOL DATA BLOCK...................... 21
; 16. RMV??? REMOVE DATA BLOCKS TO FEE CORE..................... 22
; 17. SUROUTINE TO RETURN STORAGE DATA BLOCK TO THE MONITOR..... 23
; 18. SUBROUTINES TO SEARCH AND DEFINE DDB' NDT'S ETC........... 27
; 19. ROUTINE TO GENERATE THE NCL PROTOCOL HEADERS.............. 28
; 20. UNNUMBERED NCS CONTOL MESSAGES............................ 29
; 21. NCS NUMBER CONTROL MESSAGES............................... 32
; 22. MEMORY CONTROL ROUTINES................................... 41
; 23. COMMON SUBROUTINES TO CONVERT EXTENSIBLE ASCII/BINARY..... 43
; 24. NETINI - INITILIZATION/ONCE A SECOND CODE................. 47
; 25. NETCTC - CALL ON RESET OR ^C^C AND NOT CCON/CON........... 48
; 26. FEKINT INTERRUPT LEVEL PROCESSINT......................... 49
; 27. OUTINT - OUTPUT INTERRUPT PROCESSOR FOR ALL FEK'S......... 51
; 28. NETWRT - SEND A MESSAGE TO THE FRONT END KONTROLLER FEK... 52
; 29. NETHIB/NETWAK - HIBERNATE AND SLEEP ROUTINE............... 53
; 30. INPDIS - DISMISS THE INPUT INTERRUPT...................... 54
; 31. INPINT - INPUT INTERRUPT PROCESSOR FOR ALL FEK'S.......... 56
; 32. CHKNCA - CHECK ACK'S FOR MESSAGE SENT BUT BEING HELD...... 57
; 33. - PROCESS THE TOPS MESSAGE ON THE QUEUE IN SEQUENCE....... 58
; 34. INCTID - NODE ID MESSAGE PROCESSOR........................ 59
; 35. INCTDM - PROCESS OF NUMBERED CONTROL/DATA MESSAGES........ 63
; 36. ICMXXX MESSAGE PROCESSORS................................. 64
; 37. ICMCNN - NODE IS ATTEMPTING TO CONNECT TO A DEVICE OR TASK 65
; 38. ICMDSC - DISCONNECT....................................... 66
; 39. RQBOOT - AUTO RELOAD OF A DAS80,81,82,DC72 REMOTE STATION. 72
; 40. NCSIDC - DEVICE CONTROL FOR INPUT MESSAGES................ 73
; 41. IDCDAT (1) DATA WITHOUT END OF RECORD..................... 74
; 42. IDCDAR (2) DATA WITH END OF RECORD (MTA'S)................ 74
; 43. IDCSTS (3) STATUS......................................... 75
; 44. IDCCMN (4) CONTROL MESSAGE................................ 76
; 45. IDCUID (5) USER ID........................................ 77
; 46. IDCFSP (6) FILE SPEC...................................... 77
; 47. COMMON DEVICE DEPENDENT ROUTINES.......................... 82
; 48. TELETYPE DEVICE-DEPENDENT CODE............................ 83
; 49. TTYDSC REMOTE DATA SET CONTOL FOR DAS80'S SERIES.......... 91
; 50. TTYSTS/TTYCHR STATUS AND CHARASTICS....................... 92
; 51. NCS CONTROL MESSAGES...................................... 93
; 52. DAP CONTROL MESSAGES...................................... 94
; 53. HOST.U - SET HOST UUO TO SWITCH BETWEEN COMMAND DECODERS.. 111
; 54. HOST.C - SET HOST COMMAND TO SWITCH BETWEEN MCR'S......... 112
; 55. LOCAL STORAGE FOR NETSER.................................. 113
; 56. DEVICE DATA BLOCKS........................................ 114
; 57. LPTCRF - PRINT A CRLF AS FIRST OUTPUT AFTER INIT.......... 118
; 58. DEVICE DATA BLOCKS........................................ 120
; 59. DEVICE DATA BLOCKS........................................ 131
SUBTTL DEVICE DATA BLOCKS AND OTHER SYMBOLS
;SPECIAL BITS IN LH(S)
IOSCLO==400 ;DEV HAS BEEN CLOSED
IOSREL==1000 ;DEV HAS BEEN RELEASED
IOSUUD==2000 ;UUO PROCESSING DELAYED
IOSCON==4000 ;DEVICE IS CONNECTED
IOSERR==10000 ;ERROR DETECTED AT INT. LEVEL
IOSHDV==100000 ;HUNG DEVICE
;HIGH TWO BITS ARE FOR DEVICE-DEPENDENT FUNCTIONS
TIMFAC==^D9835 ;FACTOR USED BY NET2ND TO KEEP AN EXPONENTIAL
; AVERGE OF BUFFER USAGE WITH A ONE MINUTE
; TIME CONSTANT. THIS VALUE IS EQUAL TO
; EXP(-1/TIMECONSTANT)
;ENTRY FROM COMCON WITH A NETWORK ASSIGN COMMAND
; ASSIGN NODENAME_DEV:LOGICAL
;COMCON HAS ALREADY SCANNED OF THE NODE NAME
;T2=NODE NAME
;T3=DELIMETER
NETASG:: ;ENTRY
MOVE P1,T2 ;SAVE THE STATION NAME
CAIN T3,"_" ;TERMINATED BY A _
PUSHJ P,COMTYS## ;YES, SKIP THE CHARACTER
MOVE T1,P1 ;GET THE NODE NAME AGAIN
PUSHJ P,CVTOCT## ;TRY FOR OCTAL
CAIA ;NO MUST BE SIXBIT
MOVE P1,T1 ;YES, USED OCTAL NAME
PUSHJ P,CTXDEV## ;GET THE DEVICE NAME
JUMPE T2,NOTENF## ;ILLEGAL ARG LIST
MOVE P2,T2 ;SAVE THE DEVICE NAME
TRNE T2,505050 ;MUST BE NUMBERIC GGNN,GG,N
JRST NOTDEV## ;ERROR RETURN
;HERE TO VALIDATE THE STATION NAME
MOVE T1,P1 ;COPY THE STATION NAME
PUSHJ P,SRCNDB ;DOES THE STATION EXIST
JRST [HRRZ T1,NRTUNN ;TYPE AN ERROR
PJRST ERRMES##] ;ERROR MESSAGE
CAMN P1,JBTLOC## ;LOCAL NODE
JRST ASSIGC## ;YES, JUST RETURN
MOVEI P1,(W) ;SAVE THE NDB POINTER
;HERE TO VALIDATE THE REMOTE DEVICE NAME
HLRZ T1,P2 ;GENERIC NAME ONLY FROM THE LEFT HALF
TRNN P2,505050 ;MUST BE LEFT HALF NUMBERIC OR ZEROS
PUSHJ P,SRCNDT ;SEARCH THE NDT
PJRST NOTDEV## ;NOT A LEGAL DEVICE
HLL P2,NDTNAM##(W) ;COPY THE GENERIC -10 DEVICE NAME
MOVEI W,(P1) ;GET THE NODE POINER BACK
HLRZ P1,NDBNNM##(W) ;PUT THE NODE NUMBER IN P1
;HERE TO CONVER THE DEVICE NAME INTO A NETWORK NAME
;DEVICE MUST BE OF THE FORM(S) GGGNNU, GGGNN, GGGU,OR GGG
MOVEI T1,(P1) ;CONVERT THE NODE NUMBER TO SIXBIT
TRO T1,77700 ;FORCE CONVERSION TO LINE UP
PUSHJ P,CVTSBT## ;IN UUOCON
MOVEI T2,(P2) ;COPY THE STATION AND UNIT NUMBER IF ANY
TRNE T2,7700 ;USER SUPPLY A STATION NUMBER
JRST NETAS1 ;YES,
LSH T2,-14 ;SHIFT THE UNIT NUMBER IF ANY TO LOW ORDER
IORI T2,(T1) ;COMBINE THE RIGHT HALF
HLL T2,P2 ;AND INSERT THE GENERIC NAME
JRST ASSIGC## ;RETURN COMCON WITH T2=GGGNN(U)
NETAS1: ;USER SUPPLIED A STATION NUMBER
;FORM IS GGGNN OR GGGNNU
TRZ T2,77 ;REMOVE THE UNIT NUMBER IF ANY
CAIE T2,(T1) ;NAME AND NUMBER MUST MATCH
JRST NOTDEV## ;NO, NOT A LEGAL DEVICE NAME
MOVE T2,P2 ;YES, USE THE USERS NAME
JRST ASSIGC## ;RETURN TO COMCON
SUBTTL TSTNET - FIND OUT IF A DEVICE EXISTS ON THE NETWORK
;SUBROUTINE TSTNET - ASSIGN A DDB FOR THE DEVICE IF IT EXISTS
;CALL MOVE T1,DEVICE NAME
; PUSHJ P,TSTNET
;RETURN CPOPJ ;DEVICE DOES NOT EXIST/NOT AVAILABLE
; CPOPJ1 ;DEVICE EXISTS AND IS AVAILABLE
TSTNET:: ;ENTRY FROM UUOCON
HLRZ T2,M ;GET THE UUO
ANDI T2,777000 ;ONLY THE UUO OP CODE
CAIE T2,(OPEN) ;IS IT
POPJ P, ;NO, GET THE ASSIGN LATER
TRNE T1,7700 ;IS THERE A STATION NUMBER
PUSHJ P,DVSCVT## ;GET THE STATION NUMBER
POPJ P, ;NOT A STATION NUMBER
PUSH P,T1 ;SAVE THE NAME
DPB T1,[POINT 6,T1,23] ;MOVE THE UNIT NUMBER OVER
TRZ T1,7777 ;CLEAR THE JUNK
PUSHJ P,GENNET ;GO ASSIGN THE DEVICE
PJRST TPOPJ ;NO SUCH DEVICE
PJRST TPOPJ1## ;DEVICE ASSIGNED F=DDB
;SUBROUTINE GENNET - TEST FOR A GENERIC NETWORK DEVICE
;CALL MOVE T1,[SIXBIT /DEVNAME/]
; MOVE T2,STATION NUMBER
; PUSHJ P,GENNET
;RETURN POPJ ;NO ON THE NETWORK OR AVAILABLE
; CPOPJ1 ;F=DDB ADDRESS
GENNET:: ;ENTRY FROM UUOCON
CAMN T2,JBTLOC## ;LOCAL STATION
POPJ P, ;YES, RETURN
PUSHJ P,SAVT## ;NO, SAVE THE T'S
MOVEI T4,(P) ;GET THE STACK ADDRESS
CAMG T4,LOCORE## ;RUNNING AT CLOCK LEVEL
POPJ P, ;YES, DON'T TRY THE NETWORK
PUSHJ P,SAVJW ;SAVE J AND W
PUSHJ P,SAVE3## ; AND THE P'S
MOVE P2,T1 ;COPY THE DEVICE NAME
MOVEI T1,(T2) ;PUT THE STATION NUMBER IN T1
PUSHJ P,SRCNDB ;DOES THE STATION EXIST
POPJ P, ;NO EXIT
MOVEI P1,(W) ;SAVE THE NDB POINTER
SETZ P3, ;CLEAR THE LOCAL NAME
HLRZ T1,P2 ;GET THE GENERIC DEVICE NAME
PUSHJ P,SRCNDT ;SEE IF IT EXISTS AT THE STATION
POPJ P, ;NO, EXIT
PUSHJ P,MAKDDB ;YES, MAKE A DDB
POPJ P, ;CAN'T
PUSHJ P,NCSCNT ;CONNECT THE DEVICE
PJRST RMVNET ;FAILED DISCARD DDB
PUSHJ P,LNKDDB
PJRST CPOPJ1## ;WE WON
NODERT: XWD [ASCIZ / Assigned/]
NRTDNA: XWD [ASCIZ /Device Not Available/]
NRTNCE: XWD [ASCIZ /Network Capacity Exceeded/]
NRTTNA: XWD [ASCIZ /Task Not Available/]
NRTUNT: XWD [ASCIZ /Undefined Network Task/]
NRTUNN::XWD [ASCIZ /Undefined Network Node/]
NRTUND: XWD [ASCIZ /Undefined Network Device/]
SUBTTL INTERFACE TO COMCON FOR THE "NODE" COMMAND
; C NODE,NODE.C##,NOCORE
NODE.C::SKIPN JBTADR##(J) ;ANY CORE ASIGNED
PUSHJ P,GETMIN## ;NO, GET SOME CORE
JUMPE R,DLYCM## ;WAIT
PUSHJ P,SAVCTX## ;SAVE THE CONTEXT OF THE JOB
PUSHJ P,CTEXT1## ;GET THE ARGUMNET
SKIPN T1,T2 ;CHECK FOR AN ARG
JRST NODEC1 ;NONE LIST ALL
PUSHJ P,CVTOCT## ;CONVERT TO OCTAL IF POSSIBLE
JFCL ;NO, MUST HAVE BEEN A NODE NAME
; JRST NODEC6 ;FALL THRU
;TYPE OUT A PARTICULAR NODE NAME
NODEC6: PUSHJ P,SRCNDB ;FIND THE NODE BLOCK
PJRST [HRRZ T1,NRTUNN ;GET THE ERROR MESSGE
PJRST ERRMESS##] ;TYPE IT
PJRST NODEC2 ;TYPE THE INFO
;TYPE OUT THE KNOWN NODES
NODEC1: ;NO ARG ON NODE COMMAND
MOVEI W,NETNDB## ;GET THE START OF THE CHAIN
NODEC7: PUSHJ P,NODEC2 ;TYPE OUT THE PARAMS
HRRZ W,NDBNNM##(W) ;GET THE NEXT NDB
JUMPN W,NODEC7 ;CONTINUE
POPJ P, ;RETURN
NODEC2: PUSHJ P,TYPNDB ;TYPE IT
PUSHJ P,INLMES## ;TYPE CR-LF-TAB
ASCIZ /
/
MOVSI P1,-<OBJ.MX+1> ;GET THE DEVICE TABLE SIZE
NODEC4: LDB T1,NETCNF##(P1) ;GET THE NUMBER OF DEVICES
JUMPE T1,NODEC5 ;NONE DON'T PRINT
MOVEI T1,(P1) ;GET THE DEVICE NUMBER
ROT T1,-1 ;DEVICE BY 2
HLLZ T2,NETDVN##(T1) ;GET THE EVEN DEVICE NAME
SKIPGE T1 ;SKIP IF EVEN
HRLZ T2,NETDVN##(T1) ;GET THE ODD ENTRY
PUSHJ P,PRNAME## ;PRINT IT OUT
MOVEI T3,"[" ;BRACKET
PUSHJ P,COMTYO## ;TYPE
LDB T1,NETCNF##(P1) ;GET THE NUMBER OF ENTRIES
PUSHJ P,RADX10## ;PRINT
PUSHJ P,INLMES## ;BRACKET SPACE
ASCIZ /] /
NODEC5: AOBJN P1,NODEC4 ;CONTINUE TO THE END
PJRST PCRLF## ;CR-LF
SUBTTL INTERFACE TO UUOCON FOR THE NODE UUO
; X NODE.,NODE.U##,UU.LEA
NODE.U:: ;ENTRY POINT
HLRZ T4,T1 ;GET THE FUNCTION IN T4
SKIPE T4 ;NOT ZERO
CAILE T4,NUULEN ;CHECK THE LENGTH
JRST ECOD1## ;ILLEGAL RETURN 1
HRRI M,(T1) ;GET THE ARG LIST IN M
JRST UUOTAB-1(T4) ;JUMP ON THE FUNCTION TYPE
UUOTAB: ;NODE UUO FUNCTIONS
JRST NODE.1 ;ASSIGN A DEVICE
JRST NODE.2 ;RETURN A NODE NUMBER
JRST NODE.3 ;STATION CONTOL MESSAGE
JRST NODE.4 ;AUTO RELOAD OF DAS 80 SERIES
JRST NODE.5 ;RETURN CONFIG INFO FOR NODE
NUULEN==.-UUOTAB ;LENGTH OF THE TABLE
SUBTTL NODE.1 - ASSIGN A REMOTE DEVICE
NODE.1: PUSHJ P,SAVE4## ;SAVE THE P'S
PUSHJ P,GETWDU## ;GET THE ARGUMENT LIST SIZE
CAIE T1,4 ;MUST HAVE FOUR ARGS
JRST ECOD1## ;ILLEGAL ARG LIST
PUSHJ P,GETWD1## ;GET THE NODE NAME
PUSHJ P,SRCNDB ;CHECK IF DEFINED
JRST ECOD2## ;NO, ILLEGAL NODE NAME
HLRZ T1,NDBNNM##(W) ;GET NODE NUMBER
CAMN T1,JBTLOC## ;IS IT LOCAL SITE?
JRST ECOD2## ;YES, CAN'T ASSIGN LOCAL DEVICE
MOVEI P1,(W) ;SAVE THE NODE DATA BLOCK
PUSHJ P,GETWD1## ;GET THE PHYSICAL DEVICE NAME
SKIPN P2,T1 ;COPY THE NAME
JRST ECOD3## ;ZERO IS ILLEGAL
HLRZS T1 ;GENERIC NAME ONLY FOR SEARCH
PUSHJ P,SRCNDT ;SEARCH THE DEFINED NAME TABLE
JRST ECOD3## ;ILLEGAL DEVICE NAME
PUSHJ P,GETWD1## ;GET THE LOGICAL NAME
MOVE P3,T1 ;COPY THE NAME
PUSHJ P,MAKDDB ;MAKE A REMOTE NETWORK DDB
JRST ECOD4## ;NO CORE AVAILABLE
PUSHJ P,NCSCNT ;CONNECT THE DEVICE
JRST [MOVEI T1,10(T1);STEP UP THE ERROR NUMBER
PUSHJ P,STOTAC## ;TELL CALLER WHY IT FAILED
PJRST RMVNET] ;REMOVE DDB FROM SYSTEM
PUSHJ P,LNKDDB ;LINK IS NEW DDB
MOVEI T1,ASSCON ;NOW SET THE
IORM T1,DEVMOD(F) ; "ASSIGNED" BIT
JRST CPOPJ1## ;CONNECT OK EXIT
SUBTTL NODE.2 RETURN A NODE NUMBER IN THE AC
NODE.2: ;ENTRY
PUSHJ P,GETWDU## ;GET THE ARG COUNT
CAIE T1,2 ;MUST BE A 2
JRST ECOD1## ;NO ILLEGAL FUNCTION
PUSHJ P,GETWD1## ;GET THE NODE NAME
PUSHJ P,NODE.S ;FIND CORRECT NDB
PJRST ECOD2## ;ILLEGAL NODE
MOVE T2,T1 ;COPY ARGUMENT
HLRZ T1,NDBSNM##(W) ;GET THE NAME POINTER
MOVE T1,(T1) ;GET THE NAME
TLNE T2,-1 ;WANTS A NAME?
HLRZ T1,NDBNNM##(W) ;NO, GET THE NODE NUMBER
PJRST STOTC1## ;RETURN NODE NUMBER IN AC
;SUBROUTINE TO FIND NDB FOR NODE.UUO FUNCTIONS
;CALL T1 = ARGUMENT TO NODE.UUO
;RETURNS CPOPJ IF NOT FOUND
; CPOPJ1 WITH W SET TO NDB, RESPECTS T1
NODE.S: PUSH P,T1 ;SAVE ARGUMENT
PUSHJ P,CVTOCT## ;CHECK #
MOVE T1,0(P) ;NOPE, RESTORE ARG
PUSHJ P,SRCNDB ;SCAN NDB'S
PJRST TPOPJ## ;NOPE, GIVE ERROR
PJRST TPOPJ1## ;RETURN WITH W SET UP
SUBTTL NODE.3 STATION CONTROL MESSAGES
;FORMAT OF THE UUO ARGS
; XWD TIME,COUNT
; SIXBIT /NODE NAME/ OR NUMBER
; XWD COUNT,ADR OF OUTPUT BUFFER
; XWD COUNT,ADR OR RESPONSE BUFFER
NODE.3: PUSHJ P,SAVE4## ;SAVE P1
MOVE R,JBTADR##(J) ;GET THE RELOCATION
MOVSI T1,JP.POK ;CHECK FOR A POKE
PUSHJ P,PRVBIT## ;CHECK IT
CAIA ;YES
JRST ECOD3## ;NOT A PRIV JOB
MOVSI T1,NSHF!NSWP ;LOCKED BITS
TDNN T1,JBTSTS##(J) ;IS THE LOW SEGMENT ALREADY LOCKED?
JRST ECOD5## ;MUST BE LOCKED IN CORE
TRNN M,777760 ;NO IN THE AC'S
PJRST ECOD1## ;ERROR
MOVEI P1,(M) ;SAVE THE UUO POINTER
HRLI P1,(J) ;AND THE JOB NUMBER
PUSHJ P,GETWDU## ;GET THE ARGUMENT COUNT AND FLAGS
MOVS P3,T1 ;COPY THE TIME
ANDI T1,-1 ;SAVE THE ARG COUNT
CAIL T1,3 ;CHECK THE COUNT
CAILE T1,4 ;FOR RANGE 3-4
JRST ECOD3## ;ERROR
PUSHJ P,GETWD1## ;GET THE NODE NAME
PUSHJ P,SRCNDB ;FINDE THE STATION
JRST ECOD2## ;ILLEGAL STATION OR NUMBER
HLRZ T1,NDBNNM##(W) ;GET THE NODE NUMBER
CAMN T1,JBTLOC## ;IS THIS THE LOCAL STATION
JRST ECOD2## ;YES, GIVE AN ERROR
MOVSI T1,NDB.SK## ;GET STACK SEEN OR SENT FLAG
TDNN T1,NDBFEK##(W) ;HAS NODE FINISHED NCL STARTUP?
PJRST ECOD2## ;NO, WE CAN'T SEND A NUMBERED MSG TO IT
SKIPE T1,SCBCTL##(W) ;IS STATION CONTROL AVAILABLE
JRST ECOD4## ;NO NOT AVAILABLE IN USE
PUSHJ P,GETWD1## ;GET THE MESSAGE POINTR
MOVE P4,T1 ;SAVE THE ARG
JUMPE T1,ECOD1## ;ILLEGAL
ANDI T1,-1 ;ONLY 18 BITS
PUSHJ P,IADRCK## ;CHECK THE ADDRESS(MAY PAGE FAULT)
PJRST ECOD1## ;NOT IN RANGE
HLRZ T2,P4 ;GET THE BYTE COUNT
ROT T2,-2 ;CONVER TO WORDS
TLNE T2,600000 ;CHECK FOR A CARRY
ADDI T2,1 ;STEP WORD BY ONE
ADDI T1,-1(T2) ;END OF THE ARRAY
TRNN T2,777400 ;ONLY 512 BYTE IS MAX
PUSHJ P,IADRCK## ;CHECK IT
PJRST ECOD1## ;ADDRESS ERROR
HLRZ T1,P3 ;ARG COUNT
CAIE T1,4 ;RESPONSE ?
JRST CPOPJ1## ;NONE
PUSHJ P,GETWD1## ;GET THE INPUT BUFFER ADDRESS
JUMPE T1,CPOPJ1## ;NO RESPONSE REQUIRED
MOVE P2,T1 ;SAVE
ANDI T1,-1 ;CLEAR THE BYTE COUNT
PUSHJ P,IADRCK## ;CHECK IT
JRST ECOD1## ;ERROR
HLRZ T1,P2 ;GET THE BYTE COUNT
ROT T2,-2 ;CONVERT TO WORDS
TLNE T2,600000 ;CARRY
ADDI T2,1 ;ONE MORE WORD
ADDI T1,-1(T2) ;POINT TO THE END OF THE ARRAY
PUSHJ P,IADRCK## ;CHEDK IT
JRST ECOD1## ;ERROR
MOVEM P1,SCBCTL##(W) ;STORE THE POINTER
MOVE T1,P4 ;FINALLY TIME TO SEND STATION CONTROL MSG
PUSHJ P,NCSCTL ;BUILD AND SEND IT
JRST [SETZM SCBCTL##(W) ;NO ROOM I GUESS. FREE THIS
JRST ECOD4##] ;AND RETURN ERROR TO CALLER
HLRZ T1,NDBNNM##(W) ;GET THE NODE NUMBER
PUSH P,T1 ;SAVE OVER CALL FOR HIBER
MOVEI T1,(P3) ;GET THE TIME REQUEST
ANDI T1,777 ;ONLY NINE BITS WORTH
IMULI T1,^D1000 ;MS TO SLEEP
PUSHJ P,HIBER## ;WAIT
JFCL
POP P,T1 ;RESTORE THE NODE NUMBER
PUSHJ P,SRCNDB ;IS THE NODE STILL UP
JRST ECOD2## ;NODE WENT AWAY
SKIPE SCBCTL##(W) ;WAKE FOR US
JRST [SETZM SCBCTL##(W) ;TIMED OUT
JRST ECOD6##] ;GIVE ERROR RETURN
PJRST CPOPJ1## ;EXIT MESSAGE SENT/RECEIVED
SUBTTL NODE.4 AUTO RELOAD OF DOWN LINE DAS80 SERIES REMOTE STATIONS
;FORMAT OF THE UUO ARGS
; XWD TIME,COUNT
; XWD 0,0
; XWD 0,0
; XWD COUNT,ADR OF RESPONSE BUFFER
NODE.4: ;ENTRY
PUSHJ P,SAVE2## ;SAVE P1,2,3
MOVEI W,NETNDB## ;SEARCH FOR A NODE WITH A BOOT MESSAGE
NODE41: HRRZ W,NDBNNM##(W) ;GET THE NEXT ENTRY
JUMPE W,ECOD2## ;NONE AVAILABLE
HRRZ P1,SCBRQB##(W) ;IS A REQUEST BOOT AVAILABLE
JUMPE P1,NODE41 ;CONTINUE
SETZM SCBRQB##(W) ;MAKE BOOT AVAILABLE
ADDI M,1 ;POINT TO THE NODE NAME WORD
HLRZ T1,NDBSNM##(W) ;GET THE NAME POINTER
MOVE T1,(T1) ;GET THE NAME
PUSHJ P,PUTWDU## ;STORE THE NAME IN THE ARG LIST
ADDI M,2 ;POINT TO THE RECEIVE BUFFER
PUSHJ P,GETWDU## ;GET THE ARGUMENT
MOVE P2,T1 ;COPY
JUMPE T1,ECOD1## ;ILLEGAL
ANDI T1,-1 ;ADDRESS CHECK
PUSHJ P,IADRCK## ;THE BUFFER ADDRESS
PJRST ECOD1## ;ILLEGAL
HLRZ T2,P2 ;GET THE BYTE LENGTH
ADDI T2,3 ;ROUND UP
LSH T2,-2 ;TO WORDS
ADDI T1,-1(T2) ;POINT TO THE END OF THE ARRAY
PUSHJ P,IADRCK## ;ADDRESS CHECK
PJRST ECOD1## ;ERROR
HLRZ T2,P2 ;GET THE BYTE COUNT
HRRZ T1,(P1) ;GET THE BYTE COUNT
CAIGE T2,(T1) ;WILL IT FIT
MOVEI T1,(T2) ;NO, USER THE USERS SIZE (TRUNCATE)
HRLI P2,(T1) ;STORE THE READ BYTE COUNT
ADDI T1,3 ;CONVERT TO WORDS
LSH T1,-2 ;AND ROUND UP
ADDI T1,-1(P2) ;TERMINATE THE BLT POINTER
HRLI T2,1(P1) ;BLT POINTER
HRRI T2,(P2) ;TO MOVE THE MESSAGE
IFN FTKA10,<
ADDI T1,(R) ;RELOCATE FOR KA10
ADDI T2,(R) ;..
>
EXCTXU <BLT T2,(T1)>;MOVE THE MESSAGE
MOVE T1,P2 ;GET THE ARGUMENT
PUSHJ P,PUTWDU## ;STORE THE BYTE COUNT
HLRZ T1,(P1) ;GET THE SIZE
MOVEI T2,(P1) ;GET THE ADDRESS
PUSHJ P,GIVZWD ;RETURN THE SPACE
PJRST CPOPJ1## ;EXIT
SUBTTL NODE.5 RETURN CONFIG INFO FOR NODE
;FORMAT OF THE UUO ARGS
; XWD 0,,COUNT
; SIXBIT /NODE NAME/ OR NUMBER
; 0 RESERVED FOR DATE AND NAME
; BLOCK <COUNT-3> INFO RETURNED HERE
NODE.5: PUSHJ P,SAVE1## ;SAVE P1 FIRST
PUSHJ P,GETWDU## ;GET ARGUMENT LIST SIZE
SUBI T1,3 ;DEDUCT OVERHEAD
CAIG T1,^D1000 ;RIDICULOUS SIZE
SKIPG P1,T1 ;ANY ROOM LEFT FOR ANSWER
PJRST ECOD1## ;NO, ILLEGAL ARG LIST
PUSHJ P,GETWD1## ;GET NODE NAME
PUSHJ P,NODE.S ;FIND CORRECT NDB
PJRST ECOD2## ;ILLEGAL NODE
PUSHJ P,GETWD1## ;GET RESERVED WORD
JUMPN T1,ECOD7## ;MUST BE ZERO
NODE51: PUSHJ P,GETWD1## ;GET DEVICE TYPE REQUEST
MOVSI T2,-<OBJ.MX+1> ;NUMBER OF KNOWN DEVICES
MOVE T3,[POINT 6,NETTRN##] ;TRANSLATION TABLE
NODE52: ILDB T4,T3 ;GET A TYPE
CAIE T4,(T1) ;FOUND REQUEST
AOBJN T2,NODE52 ;NO, TRY ANOTHER TYPE
SKIPGE T2 ;FIND ANY
SKIPE SCBTTY##(W) ;ANY OUTSTANDING CONNECTS
TDZA T2,T2 ;NONE OF REQUESTED TYPE
LDB T2,NETCNF##(T2) ;GET NUMBER OF THAT TYPE
HRL T1,T2 ;INSERT COUNT FOR USER
PUSHJ P,PUTWDU## ;STORE BACK
SOJG P1,NODE51 ;DO FOR ALL ARGS
PJRST CPOPJ1## ;GIVE GOOD RETURN
SUBTTL SCB INTERFACE ROUTINES
;SUBROUTINE TO LOAD INTO T1 THE TTY NUMBER OF THE OPR'S
; TTY FOR THE STATION WHOSE NUMBER IS IN T1.
STBOPR::PUSH P,U ;SAVE U
HRRZS T1 ;STATION NUMBER IN T1
PUSHJ P,SRCNDB ;FIND THE NODE BLOCK
JRST LCLOPR ;NO, USE LOCAL OPR
HRRZ U,SCBOPR##(W) ;GET THE OPR LDB
SKIPN U ;ANY ASSIGNED
LCLOPR: MOVE U,OPRLDB## ;NO, USE LOCAL OPR
LDB T1,LDPLNO## ;GET NUMBER OF TTY IN U
JRST UPOPJ## ;RESTORE U AND EXIT.
;SUBROUTINE STBSCA - RETURN THE STATION NUMBER
;CALL MOVEI T1,NNM
; PUSHJ P,STBSCA
;RETURN CPOPJ ;NO SUCH STATION
; CPOPJ1 ;STATION VALID T1=NNM
STBSCA:: ;ENTRY
PUSHJ P,SAVJW ;SAVE J AND W
PUSHJ P,SRCNDB ;SEARCH THE NODE DATA BLOCKS
POPJ P, ;RETURN INVALID STATION
HLRZ T1,NDBNNM##(W) ;GET THE STATION NUMBER
PJRST CPOPJ1## ;EXIT
SUBTTL MAKDDB - SUBROUTINE TO BUILD A NETDDB
;CALL MOVE P1,NDB POINTER
; MOVE P2,DEVICE NAME
; MOVE P3,LOGICAL NAME
; MOVE W,NDT POINTER
; PUSHJ P,MAKDDB
;RETURN CPOPJ ;NO SPACE AVAILABLE
; CPOPJ1 ;F=DDB POINTER,U=PCB
MAKDDB::MOVEI T2,NETLEN## ;GET THE LENGTH OF THE PROTOTYPE DDB
PUSHJ P,GETZWD ;ALLOCATE THE SPACE
POPJ P, ;SPACE NOT AVAILABLE
MOVEI F,(T1) ;COPY THE DDB POINTER
HRLI T1,NETDDB## ;BLT POINT TO COPY THE PROTOTYPE DDB
BLT T1,NETLEN##-1(F);COPY IT
HRRZM P1,DEVNET(F) ;STORE THE NDB POINTER
MOVEM P2,DEVNAM(F) ;STORE THE DEVICE NAME
MOVEM P3,DEVLOG(F) ;STORE THE LOGICAL NAME
HLRZ T1,NDBNNM##(P1) ;GET THE NODE NUMBER
DPB T1,PDVSTA## ;STORE AS THE STATION NUMBER
HLRZ T1,NDBNNM##(P1) ;GET THE NODE NUMBER
TRO T1,77700 ;FORCE A STATION NUMBER ALIGNMENT
PUSHJ P,CVTSBT## ;CONVERT TO SIXBIT
MOVE T2,P2 ;COPY THE DEVICE NAME
TRNN T2,7777 ;CHECK FOR GGGU
LSH T2,-14 ;YES, SHIFT FOR THE UNIT NUMBER
ANDI T2,77 ;ONLY ONE DIGIT
IORI T1,(T2) ;INSERT THE DIGIT
HRRM T1,DEVNAM(F) ;STORE IN THE DEVNAME
ANDI T1,77 ;SAVE LAST DIGIT
SKIPN T1 ;IS IT A BLANK IE GENERIC
TROA T1,177 ;YES, USE 177 FOR GENERIC SEARCH
ANDI T1,7 ;ONLY THREE BITS WORTH (FOR GGGNNU)
DPB T1,PUNIT## ;STORE THE UNIT NUMBER
MAKDD6: MOVSI T1,DVCNET ;GET THE NETWORK OWNERSHIP BIT
IORM T1,DEVCHR(F) ;STORE WE OWN IT
DPB J,PJOBN## ;STORE THE JOB NUMBER
LDB T1,NDTBFZ## ;GET THE DEFAULT BUFFER SIZE
DPB T1,PBUFSZ## ;STORE THE BUFFER SIZE
LDB T1,NDTTYP## ;GET THE DEVICE TYPE
DPB T1,DEYTYP## ;STORE THE DEVICE TYPE
MOVE T1,NDTMOD##(W) ;GET THE DEVMOD BITS
MOVEM T1,DEVMOD(F) ;STORE DEVMOD
HRLM W,DEVNET##(F) ;LINK THE NDT TO THE DDB
;HERE TO ASSIGN A SLA
HRRZ T2,F ;GET ADDRESS TO STORE IN NETLAT
PUSHJ P,GETSLA ;GET A SLA
JRST RMVNE1 ;NONE AVAILABLE
DPB T1,NETSLA## ;STORE THE SLA
JRST CPOPJ1## ;EXIT WITH F=NETDDB, U=PCB, W=NDT
SUBTTL MBF - INTERNAL MONITOR BUFFER ROUTINES
;
; FORMAT OF THE INTERNAL MONITOR BUFFERS
;
PHASE 0
MBFMXC::!0 ;MAX NUMBER OF MBF BUFFERS
MBFBFC::!0 ;CURRENT FILLED BUFFER COUNT
MBFIBC::!0 ;INPUT BUFFER POINTER
MBFOBC::!0 ;OUTPUT BUFFER POINTER
MBFCHK::!0 ;CHECKSUM FOR BINARY CARDS
MBFMBF::!BLOCK 0*0 ;MONITOR BUFFERS
MBFSDS::! ;LENGTH
DEPHASE
RELOC .-MBFSDS ;RECLAIM STORAGE SPACE
;SUBROUTINE BLDMBF - BUILD A SET OF INPUT MONITOR BUFFERS
;CALL MOVE T1,[XWD #BUFFERS,SIZE]
; PUSHJ P,BLDMBF
;RETURN CPOPJ ;WHEN THE BUFFERS ARE BUIT
BLDMBF:: ;ENTRY
SKIPE NETDEV##(F) ;DOES A BUFFER EXIST
STOPCD .+1,DEBUG,MBE,;++MONITOR BUFFER EXISTS
PUSH P,T1 ;SAVE THE ARGUMENT
HLRZ T2,T1 ;NUMBER OF BUFFERS
IMULI T2,(T1) ;TIMES THE SIZE OF EACH
ADDI T2,MBFMBF-MBFMXC;PLUS THE CONTROL INFORMATION
HRRM T2,0(P) ;STORE THE SIZE
PUSHJ P,SLPZWD ;ALLOCATE THE SPACE
POP P,T2 ;GET BACK NUMBER,,TOTAL SIZE
HLRZM T2,MBFMXC(T1) ;STORE BUFFER COUNT
HRL T1,T2 ;T1:=TOTAL SIZE,,ADR OF MON BUFFERS
MOVEM T1,NETDEV##(F) ;STORE IN DDB
POPJ P, ;BETURN WITH T1:=NETDEV WORD
;SUBROUTINE NETBCL - CLEAR A USER'S BUFFER
;CALL PUSHJ P,NETBCL
;RETURN CPOPJ
NETBCL::LDB T1,[POINT 12,@DEVIAD(F),17] ;GET THE BUFFER SIZE
MOVEI T2,@DEVIAD(F) ;BUFFER ADDRESS
HRLI T2,2(T2) ;FIRST DATA WORD
ADDI T2,3 ;FIRST DATA WORD
SETZM -1(T2) ;CLEAR THE FIRST WORD
ADDI T1,-4(T2) ;END OF THE BUFFER
BLT T2,(T1) ;CLEAR IT
POPJ P, ;RETURN
SUBTTL AVOMBF - AVDVNCE AN OUTPUT MONITOR BUFFER
;CALL MOVEI F,DDB
; PUSHJ P,AVOMBF
;RETURN CPOPJ ;NO DATA PENDING
; CPOPJ1 ;BUFFER IS AVDVNCED AND CONTAINS NEW DATA
AVOMBF::
SKIPN T2,NETDEV##(F) ;GET THE MONITOR BUFFER ADDRESS
JRST AVIMB1 ;NONE, BAD NEWS
AOS T1,MBFOBC(T2) ;ADVANCE TO THE NEXT BUFFER
CAMN T1,MBFMXC(T2) ;TIME TO WRAP AROUND
SETZM MBFOBC(T2) ;YES, RESET TO ZERO
SOSLE T1,MBFBFC(T2) ;REDUCE THE AMOUNT OF BUFFER IN USE
AOS (P) ;ANOTHER CARD
SKIPGE T1 ;DID INTERRUPT LEVEL CHANGE THE COUNT
AOS MBFBFC(T2) ;YES, ACCOUNT FOR THE SOS
POPJ P, ;RETURN NO BUFFERS AVAILABLE
;SUBROUTINE AVIMBF - AVOANCE AN INPUT MONITOR BUFFER
;CALL MOVEI F,DDB
; PUSHJ P,AVIMBF
;RETURN CPOPJ ;BUFFER IS AVOANCED
AVIMBF::
SKIPN T2,NETDEV##(F) ;GET THE MONITOR BUFFER ADDRESS
AVIMB1: STOPCD CPOPJ##,DEBUG,NMF,;++NO MONITOR BUFFER
AOS T1,MBFIBC(T2) ;UPDATE THE BUFFER COUNT
CAMN T1,MBFMXC(T2) ;TIME TO WRAP AROUND
SETZM MBFIBC(T2) ;YES, RESET TO ZERO
AOS MBFBFC(T2) ;INCREMENT THE NUMBER OF BUFFERS WITH DATA
POPJ P, ;RETURN
;SUBROUTINE DRQMBF - ROUTINE TO SEND DATA REQUEST BASED ON EMPTY MONITOR BUFFERS
;CALL MOVEI F,DDB
; PUSHJ P,DRQMBF
;RETURN CPOPJ
DRQMBF:: ;ENTRY
MOVE S,DEVIOS(F) ;FIRST MAKE SURE THAT THE DEVICE
TLNN S,IOSCON ; IS STILL CONNECTED. IF IT'S NOT
POPJ P, ; WE HAD BETTER LEAVE NOW OR WE WILL DIE
SKIPN T4,NETDEV##(F) ;GET THE MONITOR BUFFER ADDRESS
JRST AVIMB1 ;NO MONITOR BUFFER
MOVE T1,MBFMXC(T4) ;GET THE NUMBER OF BUFFERS ALLOWED
SUB T1,MBFBFC(T4) ;MINUS CUFFERNT COUNT =FREE
JUMPLE T1,CPOPJ## ;NONE AVAILABLE
HLRZ T2,NETDRQ##(F) ;GET THE NUMBER OF OUTSTANDING RQUESTS
SUBI T1,(T2) ;MINUS THE OUTSTANDING REQUESTS
JUMPLE T1,CPOPJ## ;NON NEED FOR MORE
PUSH P,T1 ;SAVE THE COUNT
DRQMB1:PUSHJ P,NCSDRQ ;SEND THE REQUESTS
JRST [PUSHJ P,NETSLP ;WAIT FOR FREE CORE
MOVE T1,(P) ;GET THE COUNT BACK
JRST DRQMB1] ;TRY AGAIN
POP P,T1 ;GET THE REQUEST COUNT BACK
HRLZS T1 ;IN THE LEFT HALF
ADDM T1,NETDRQ##(F) ;STORE THE UPDATD COUNT
POPJ P, ;RETURN
SUBTTL MAKPCB - BUILD A PROTOCOL DATA BLOCK
;SUBROUTINE MAKPCB - BUILD A PROTOCOL DATA BLOCK
;CALL MOVEI F,DDB OR 0 IF AN NCL MESSAGE
; MOVEI W,NDB
; PUSHJ P,MAKNDB
;RETURN CPOPJ ;NO SPACE AVAILABLE
; CPOPJ1 ;U=PCB POINTER
MAKPCB: MOVEI T2,PCBLEN## ;GET THE LENGTH
PUSHJ P,GETZWD ;GET A ZERO BLOCK ON FREE CORE
POPJ P, ;NO SPACE
MOVEI U,(T1) ;COPY THE PCB POINTER
HRRM W,PCBNDB(U) ;STORE THE NDB POINTER
JUMPE F,CPOPJ1## ;EXIT IF FOR NCS
HRLM F,PCBDDB##(U) ;STORE THE DDB POINTER OR ZERO
PJRST CPOPJ1## ;EXIT U=PCB
;SUBROUTINE MAKNDB - BUILD A NODE DATA BLOCK (NDB)
;CALL MOVEI J,FEK
; MOVEI T1,NNM
; PUSHJ P,MAKNDB
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;W=NDB
MAKNDB: ;ENTRY
PUSH P,T1 ;SAVE THE NODE NUMBER
MOVEI T2,NDBLEN## ;LENGTH
PUSHJ P,GETZWD ;ALLOCAT
PJRST TPOPJ## ;NO SPACE
MOVEI W,(T1) ;COPY THE POINTER
HRRM J,NDBFEK##(W) ;STORE THE FEK POINTER
HRRZ T1,NETNDB## ;GET THE START OF THE NDB CHAIN
HRRM T1,NDBNNM##(W) ;LINK THIS NDB TO THE START
HRRM W,NETNDB## ;LINK
POP P,T1 ;GET THE NODE NUMBER
HRLM T1,NDBNNM##(W) ;STORE
PJRST CPOPJ1## ;EXIT
;SUBROUTINE GETSLA - GET A SOURCE LINK ADDRESS FROM THE LAT TABLE
;CALL MOVE T2,ADDRESS OF DDB/LDB TO BE STORED IN NETLAT
; PUSHJ P,GETSLA
;RETURN CPOPJ ;NONE AVAILABLE
; CPOPJ1 ;T1=SLA
GETSLA: ;ENTRY
MOVNI T1,LATLEN## ;GET THE LENGTH OF THE TABLE
MOVSI T1,(T1) ;MAKE A POINTER WORD
SKIPE NETLAT(T1) ;LOOK FOR AN AVAILABLE SLOT
AOBJN T1,.-1 ;CONTINUE STEPING
JUMPGE T1,CPOPJ## ;NONE AVAILABLE
CONO PI,PIOFF## ;TURN OFF THE WORLD
SKIPE NETLAT##(T1) ; WHILE WE SEE HF THIS ONE IS STILL AVAILABLE
JRST GETSL1 ;NO, TRY AGAIN
MOVEM T2,NETLAT##(T1) ;YES, SAVE THE DESIRED POINTER
CONO PI,PION## ;AND GET STARTED AGAIN
JRST CPOPJ1## ;T1=SLA
GETSL1: CONO PI,PION## ;WE WERE INTERRUPTED, RESTORE PI'S
JRST GETSLA ; AND GO LOOK AGAIN
SUBTTL RMV??? REMOVE DATA BLOCKS TO FEE CORE
;SUBROUTINE RMVPCB - REMOVE THE PCB FROM FREE CORE
;CALL MOVEI U,PCB
; PUSHJ P,RMVPCB
;RETURN CPOPJ
RMVPCB::MOVSI T1,PCB.TY## ;CHECK FOR A TTY PCB
TDNE T1,PCBBLK##(U) ;IN THE FLAG WORD
JRST [SETZM PCBNDB##(U) ;TTY PCB, CLEAR THE NDB POINTER
POPJ P,] ;RETURN
HLRZ T1,PCBICT##(U) ;GET THE COUNT
JUMPE T1,RMVPC1 ;NONE
HRRZ T2,PCBIAD##(U) ;GET THE INPUT POINTER
PUSHJ P,GIVZWD ;REMOVE THE SPACE
RMVPC1: HLRZ T1,PCBOC2##(U) ;GET THE DATA COUNT
JUMPE T1,RMVPC3 ;NONE
HRRZ T2,PCBOA2##(U) ;GET THE ADDRESS
PUSHJ P,GIVZWD ;RETURN THE SPACE
RMVPC3: MOVEI T2,(U) ;COPY THE ADDRESS
MOVEI T1,PCBLEN## ;GET THE LENGTH
PJRST GIVZWD ;RETURN THE SPACE
;SUBROUTINE RMVNET - ROUTINE TO REMOVE A NET DDB FROM THE ADDRESS SPACE
;CALL MOVE F,DDB ;MUST NOT BE LINKED
; PUSHJ P,RMVNET
;RETURN CPOPJ
UNLDDB::MOVEI T2,NETDDB## ;GET THE STARTING DDB
UNLDB1: MOVE T1,T2 ;FOLLOW THE DDB CHAIN
HLRZ T2,DEVSER(T1) ;NEXT DDB
JUMPE T2,CPOPJ## ;WENT AWAY
CAIE T2,(F) ;IS THIS THE ONE
JRST UNLDB1 ;NO CONTINUE
HLRZ T2,DEVSER(F) ;GET THE NEXT DDB
HRLM T2,DEVSER(T1) ;REMOVE THE DDB LINKS
RMVNET::
RMVNE1:
LDB T1,NETSLA## ;GET THE SOURCE LINK ADDRESS
SKIPE T1 ;SEE ASSIGNED
SETZB T1,NETLAT(T1) ;YES, CLEAR THE ENTRY
DPB T1,NETSLA## ;CLEAR THE SOURCE
IFN FTTSK,<
LDB T1,DEYTYP## ;GET THE DEVICE TYPE
CAIN T1,<.TYTSK/.TYEST> ;A RASK
PUSHJ P,RMVTSK## ;YES, REMOVE THE TASK
>;END FTTSK
HRRZ T2,NETDEV##(F) ;CHECK FOR A MONITOR BUFFER
JUMPE T2,RMVNE2 ;NO
HLRZ T1,NETDEV##(F) ;YES, GET THE SIZE
PUSHJ P,GIVZWD ;RETURN THE SPACE
RMVNE2: MOVEI T2,(F) ;GET THE DDB ADDRESS
MOVEI T1,NETLEN## ;ANE THE LENGTH
PJRST GIVZWD ;REMOVE THE DDB AND EXIT
SUBTTL SUBROUTINE TO RETURN STORAGE DATA BLOCK TO THE MONITOR
;SUBROUTINE RMVNDB - REMOVE A NODE DATA BLOCK NDB
;CALL MOVEI W,NDB
; PUSHJ P,RMVNDB
;RETURN CPOPJ
RMVNDB: PUSHJ P,SAVJW ;SAVE J AND W
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,OFLNDB ;TYPE OFFLINE MESSAGE
IFN FTPI,<
PUSHJ P,PSINTC## ;SIGNAL NETWORK TOPOLOGY CHANGE TO THOSE INTERESTED
>
;HERE TO CHECK FOR STATION CONTROL RESOURCE
SKIPN T1,SCBCTL##(W) ;IS IT IN USE
JRST RMVNT0 ;NO CONTINUE
HLRZS T1 ;PUT THE JOB NUMBER IN T1(RT)
PUSH P,W ;SAVE W
PUSHJ P,WAKJOB## ;WAKE UP THE JOB
POP P,W ;RESTORE W
;REMOVE THE DEVICES CONNECT TO THIS NODE
;HERE TO REMOVE THE TTY'S
RMVNT0: MOVE P1,NETRTY## ;GET THE POINTER TO THE REMOTE TTY'S
RMVNT1: MOVE U,LINTAB##(P1) ;GET A TTY LDB
HLRZ T1,LDBREM##(U) ;GET THE NDB POINTER
CAIE T1,(W) ;ATTACHED TO THIS NDB
JRST RMVNT5 ;NO, LEAVE IT ALONE
PUSHJ P,CLRTTY ;CLEAR THE LDB FOR THIS TTY
PUSHJ P,RMVTTY ;DETACH THE TTY
RMVNT5: AOBJN P1,RMVNT1 ;TRY FOR ANOTHER TTY
RMVOAD: MOVE J,NDBFEK##(W) ;MARK MESSAGES QUEUED TO THIS NODE
; AS INVALID FOR OUTINT
HRRZ U,FEKOAD##(J) ;LOOK AT MESSAGE NOW GOING TO -11
JUMPE U,RMVNV0 ;NOTHING THERE, EASY
MOVSI P1,PCB.OF## ;GET NODE OFFLINE FLAG
RMVOA1: HRRZ T1,PCBNDB##(U) ;GET NDB WHO WILL GET THIS MESSAGE
CAIN T1,(W) ;SAME ONE WE WANT TO REMOVE?
IORM P1,PCBBLK##(U) ;YEP, MARK MESSAGE INVALID
HRRZ U,PCBBLK##(U) ;STEP TO NEXT MESSAGE
JUMPN U,RMVOA1 ; AND CHECK IT
;HERE TO REMOVE THE PHYSICAL DEVICE (NOT TTY'S)
RMVNV0: MOVNI P1,LATLEN## ;GET THE LENGTH OF THE LAT TABLE
MOVSI P1,(P1) ;MAKE AN AOBJN POINTER
RMVNV1: SKIPG F,NETLAT##(P1) ;GET AN ENTRY
JRST RMVNV4 ;NULL ENTRY
HRRZ T1,DEVNET(F) ;GET THE NODE POINTER
CAIE T1,(W) ;CONNECTED TO THIS NODE
JRST RMVNV4 ;NO, TRY ANOTHER
LDB J,PJOBN## ;GET THE JOB NUMBER
HRROS DEVNAM(F) ;KILL THE DEVICE NAME
PUSH P,W
IFN FTPI,<
PUSHJ P,PSIDWN## ;SIGNAL DEVICE IS DOWN
>
MOVEI T1,NRTUNN-NODERT;GET NO SUCH NODE ERROR CODE
DPB T1,NETRSN## ;SET THE REASON FOR WAKE UP
PUSHJ P,NETWAK ;WAKE THE JOB UP
MOVSI S,IOSCON ;GET THE CONNECT BIT
ANDCAB S,DEVIOS(F) ;CLEAR IT SO WE WON'T SEND A DISCONNECT
MOVEI T1,ASSCON ;GET ASSIGN BY CONSOLE
ANDCAB T1,DEVMOD(F) ;CLEAR IT SO RELEASE WILL WORK
TRNN T1,ASSPRG ;IS THE DEVICE INITED
JRST RMVNV2 ;NO
TDO S,[XWD IOSERR,IOIMPM!IODERR!IODTER!IOBKTL];SET SOME ERROR FLAGS
TRZE S,IOACT ;CLEAR IO ACT
PUSHJ P,SETIOD## ;SET IO DONE IF ACTIVE
PUSHJ P,STOIOS## ;STORE S
JRST RMVNV3 ;UUO LEVEL WILL CLEAR THE DDB FROM DEVLST
RMVNV2: PUSHJ P,RELEA9## ;NO REMOVE THE DDB
RMVNV3: POP P,W ;RESTORE THE NDB
RMVNV4: AOBJN P1,RMVNV1 ;CONTINUE
;HERE TO PURGE THE NDB NAME POINTERS
MOVEI T1,^D8 ;FOUR WORDS TO REMOVE
HLRZ T2,NDBSID##(W) ;GE THE SOFTWARE ID POINTER
SKIPE T2 ;ASSIGNED
PUSHJ P,GIVZWD ;RETURN THE SPACE
MOVEI T1,^D8 ;FOUR WORDS TO RETURN
HRRZ T2,NDBSID##(W) ;GET THE ADDRESS
SKIPE T2 ;NOT ASSIGNED
PUSHJ P,GIVZWD ;REMOVE THE SPACE
MOVEI T1,1 ;ONE WORD
HLRZ T2,NDBSNM##(W) ;GET THE STATION NAME
SKIPE T2 ;NOT ASSIGNED
PUSHJ P,GIVZWD ;RETURN THE SPACE
;HERE TO REMOVE THE QUEUES FOR THE NODES
HRRZ P1,NDBQUE##(W) ;GET THE POINTER
JUMPE P1,RMVND2 ;EMPTY
RMVND1: MOVEI U,(P1) ;GET THE NEXT ENTRY
HRRZ P1,PCBBLK##(U) ;GET THE NEXT ENTRY
PUSHJ P,RMVPCB ;REMOVE THE QUEUE ENTRY
JUMPN P1,RMVND1 ;CHECK FOR THE END
RMVND2:
HLRZ P1,NDBQUE##(W) ;GET THE POINTER
JUMPE P1,RMVND4 ;EMPTY
RMVND3: MOVEI U,(P1) ;GET THE NEXT ENTRY
HRRZ P1,PCBBLK##(U) ;GET THE NEXT ENTRY
PUSHJ P,RMVPCB ;REMOVE THE QUEUE ENTRY
JUMPN P1,RMVND3 ;CHECK FOR THE END
RMVND4:
PUSH P,W ;SAVE THE NDB POINTER
HLRZ T1,NDBNNM##(W) ;GET THE NODE NUMBER
MOVEI W,NETNDB## ;GET OUR NODE BLOCK
PUSHJ P,SRCTOP ;FIND OUT IF A NEIGHBOR
JRST RMVND7 ;NO
SETZ T1, ;MAKE A ZERO
DPB T1,T4 ;REMOVE THE NEIGHBOR
PUSHJ P,SETNBN ;SET UP TO SEND NEIGHBORS
RMVND7: POP P,W ;RESTORE THE NODE DATA BLOCK
MOVEI T1,NETNDB## ;GET THE START OF THE NDB CHAIN
RMVND5: HRRZ T2,NDBNNM##(T1) ;GET THE NEXT POINTER
JUMPE T2,CPOPJ## ;EXIT IF END
CAIN T2,(W) ;IS THIS THE BLOCK
JRST RMVND6 ;YES,
MOVEI T1,(T2) ;NO, STEP ALONG
JRST RMVND5 ;TRY AGAIN
RMVND6: HRRZ T3,NDBNNM##(W) ;GET THE FORWARD LINK
HRRM T3,NDBNNM##(T1) ;STORE BACKWARD
MOVEI T1,NDBLEN## ;GET THE LENGTH
PJRST GIVZWD ;RELEASE THE BLOCK
;SUBROUTINE LNKDDB - ADD THE DDB(F) INTO THE DDB CHAIN
;CALL MOVEI F,DDB
; PUSHJ P,LNKDDB
;RETURN CPOPJ
LNKDDB::PUSHJ P,SAVE1## ;SAVE P1
PUSH P,F ;SAVE THE DDB POINTER
MOVE T1,DEVLOG(F) ;GET THE LOGICAL NAME
PUSHJ P,DEVLG## ;CHECK FOR IN USE
JRST LNKDD1 ;NO,
SETZM DEVLOG(F) ;YES, CLEAR THE LOGICAL NAME
MOVE T2,DEVMOD(F) ;GET THE DEV MODE BITS
TLNE T2,DVDSK ;IS IT A DSK
TRNE T2,ASSPRG ; AND INIT'ED
JRST LNKDD1 ;NO IGNORE
PUSHJ P,CLRDVL## ;CLEAR LOGICAL NAME TABLE ENTRY
PUSHJ P,CLRDDB## ;YES, CLEAR THE DDB
LNKDD1: POP P,F ;RESTORE THE DDB POINTER
PUSHJ P,SETDVL## ;SET UP THE LOGICAL NAME
SKIPN DEVLOG(F) ;WAS IT BEING CLEARED
PUSHJ P,ASSCK1## ;YES, RECLAIM SPACE
MOVEI T1,NETDDB## ;GET THE PROTOTYPE
HLRZ T2,DEVSER(T1) ;GT THE LINK POINTER
HRLM T2,DEVSER(F) ;LINK THIS TO THE PROTOTYPE
HRLM F,DEVSER(T1) ;AND THE PROTOTYPE
POPJ P, ;RETURN
;SUBROUTINE ZAPDDB - REMOVE THE DDB ON A RELEASE
;CALL MOVEI F,DDB
; PUSHJ P,ZAPNET
;RETURN CPOPJ
ZAPNET:: ;ENTRY FROM UUOCON (RELEA6)
MOVSI T1,DVCNET ;NETWORK
TDNN T1,DEVCHR(F) ;DEVICE?
POPJ P, ;NO, EXIT
MOVSI T1,IOSCON ;GET THE CONNECT BIT
TDNN T1,DEVIOS(F) ;IS THE DDB CONNECTED
PJRST UNLDDB ;NO, REMOVE THE DDB
MOVE T1,.C0JOB## ;GET THE JOB NUMBER
LDB T2,PJOBN## ;GET JOB #
SKIPN T2 ;DON'T CHANGE IF THERE IS ONE
DPB T1,PJOBN## ;MUST BE A JOB NUMBER FOR THE DISCONNECT
HRRZ W,DEVNET##(F) ;GET THE NDB POINTER
ZAPNE1: LDB T1,NETDLA## ;GET THE DLA
MOVEI T2,0 ;DISCONNECT NORMAL
PUSHJ P,NCSDSC ;SEND THE MESSAGE
JRST [PUSHJ P,NETSLP ;WAIT FOR CORE TO BECOME AVAIL
JRST ZAPNE1] ;TRY AGAIN
POPJ P, ;EXIT
SUBTTL SUBROUTINES TO SEARCH AND DEFINE DDB' NDT'S ETC
;SUBROUTINE SRCNDT - SEARCH THE NETWORD DEVICE TABLE
;CALL HRRZ T1,(SIXBIT /GENERICE NETWORK DEVICE NAME/)
; MOVEI P1,NDB
; PUSHJ P,SRCNDT
;RETURN CPOPJ ;DEVICE NOT FOUND
; CPOPJ1 ;DEVICE FOUND W(RT)=THE NDT POINTER
SRCNDT::MOVE W,NDTPTR## ;GET THE SEARCH POINTER
SRCNDC: HLRZ T2,NDTNAM##(W) ;GET THE -10 DEVICE NAME
HRRZ T3,NDTNAM##(W) ;GET THE -11 DEVICE NAME
CAIE T1,(T2) ;IS IT A -10 DEVICE
CAIN T1,(T3) ;OR A -11 DEVICE
JRST SRCNDD ;CHECK THE CONFIGURATION
ADDI W,NDTLEN##-1 ;NO, STEP TO THE NEXT ENTRY
AOBJN W,SRCNDC ;AND TRY AGAIN
POPJ P, ;DEVICE NOT FOUND
SRCNDD: PUSH P,W ;SAVE THE NDT POINTER
LDB T1,NDTOBJ## ;GET THE DEVICE TYPE
MOVEI W,(P1) ;COPY THE NDB POINTER
LDB T1,NETCNF##(T1) ;GET THE CONFIGURATION COUNT
JUMPE T1,WPOPJ## ;THAT NODE DOES NOT HAVE ANY
PJRST WPOPJ1## ;DEVICE IS OK
;SUBROUTINE SRCNDB - SEARCH THE NODE DATA BLOCK
;CALL MOVE T1,NNM ;NODE NUMBER
;OR MOVE T1,[SIXBIT /NODE NAME/] ;SIXBIT NODE NAME
; PUSHJ P,SRCNDB
;RETURN CPOPJ ;NOT FOUND
; CPOPJ1 ;FOUND W=NDB POINTER
SRCNDB::JUMPE T1,CPOPJ## ;NETSER ON ZERO
MOVEI W,NETNDB## ;GET THE STARTING NDB
SRCND1: HLRZ T3,NDBNNM##(W) ;GET THE NODE NUMBER
TLNE T1,-1 ;NUMBER OR SIXBIT
JRST SRCND2 ;SIXBIT
CAIN T1,(T3) ;COMPARE
JRST CPOPJ1## ;YES, EXIT
JRST SRCND3 ;NO, STEP TO THE NEXT
SRCND2: HLRZ T2,NDBSNM##(W) ;GET THE STATION NAME POINTER
;INSERT CODE HERE FOR LONG STATION NAMES
CAMN T1,(T2) ;MATCH
JRST CPOPJ1## ;YES, EXIT
SRCND3: HRRZ W,NDBNNM##(W) ;GET THE NEXT POINTER
JUMPE W,CPOPJ## ;END OF LIST
JRST SRCND1 ;NO, CONTINUE
SUBTTL ROUTINE TO GENERATE THE NCL PROTOCOL HEADERS
;SUBROUTINE NCSHDR - CREATE<NCT><DNA><SNA><NCA><NCN>
;CALL MOVEI U,PCB
; MOVEI W,NDB
; MOVEI T1,NCT MESSAGE TYPE
; PUSHJ P,NCSHDR
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;P3=COUNT, P2=CURRENT BYTE POINTER
NCSHDR: ;ENTRY
MOVE P1,T1 ;COPY THE FLAGS
MOVEI T2,^D16 ;TEMP***
PUSHJ P,GETZWD ;ALLOCATE THE MESSAGE SPACE
POPJ P, ;NO SPACE AVAILABLE
MOVEI P2,(T1) ;MAKE A BYTE POINTER
HRLI P2,(POINT 8) ;FOR THE MESSAGE OUTPUT
MOVEM P2,PCBOAD##(U) ;STORE THE BYTE POINTER
MOVSI T1,^D16 ;GET THE SIZE
MOVEM T1,PCBOCT##(U) ;STORE
;ENTRY FOR GENERATE A HEADER FOR TTY OUTPUT
NCSTTY:
SETZ P3, ;CLEAR THE COUNT FIELD
LDB T1,NDBRFL## ;GET THE NODE FLAGS ROUTINE ETC
IORI P1,NCT.RH!NCT.SQ(T1) ;INSERT THE ADDITIONAL FLAGS
; AND THE ROUTING HEADER FLAGS
;NCT
MOVE T1,P1 ;COPY THE FLAGS
PUSHJ P,BI2EBI ;OUTPUT THE FLAGS
;DNA
HLRZ T1,NDBNNM##(W) ;GET THE DESTINATION NODE ADDRESS
PUSHJ P,BI2EBI ;OUTPUT
;SNA
MOVEI T1,NETNDB## ;ADDRESS OF THE NODE DTAT BLOCK
HLRZ T1,NDBNNM##(T1) ;GET THE SOURCE NODE ADDRESS (US)
PUSHJ P,BI2EBI ;OUTPUT
;NCA
;REAL MESSAGE NUMBER ARE ASSIGN BY NETWRT
MOVEI T1,0 ;DUMMY MESSAGE NUMBER NOW
PUSHJ P,DPBBIN ;STORE
;NCN
MOVEI T1,0 ;AGAIN
PUSHJ P,DPBBIN
;EXIT
MOVSI T1,PCB.NM## ;GET NUMBERED MESSAGE FLAG
TRNN P1,NCT.TP ;NUMBERED MESSGE
IORM T1,PCBBLK##(U) ;YES, SET THE FLAG
ADDM P3,PCBOCT##(U) ;UPDATE THE CURRENT COUNT
SETZ P3, ;CLEAR THE COUNT FIELD
PJRST CPOPJ1## ;EXIT
SUBTTL UNNUMBERED NCS CONTOL MESSAGES
;SUBROUTINE NCSSTR/NCSSAK - SEND A START/STACK MESSAGE
;CALL MOVEI W,NDB ;WHERE TO SEND THE MESSAGE
; PUSHJ P,NCSSTR/NCSSTK
;RETURN CPOPJ ;CAN'T NO CORE
; CPOPJ1 ;OK
NCSSTR: MOVSI T1,NDB.SK## ;GET THE STACK BIT
ANDCAM T1,NDBFEK##(W) ;CLAR IT
MOVEI T1,NCT.ST ;START FLAGS
SKIPA
NCSSTK: MOVEI T1,NCT.SK ;START ACK FLAGS
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSH P,T1 ;SAVE THE FLAGS
SETZ F, ;NCS MESSAGE
PUSHJ P,MAKPCB ;MAKE A PCB U=PCB
PJRST TPOPJ## ;EXIT NO CORE
MOVE T1,(P) ;GET THE MESSAGE TYPE BACK
PUSHJ P,NCSHDR ;WRITE THE HEADER
JRST [POP P,T1 ;RESTORE T1
PJRST RMVPCB] ;REMOTE THE PCB
PUSHJ P,NCSOPD ;GET THE <NNM><SNM><SID>
ADDM P3,PCBOCT(U) ;UPDATE THE COUNT
POP P,T2 ;RESTORE THE FLAGS
MOVSI T1,NDB.ST## ;GET THE START BIT
CAIE T2,NCT.ST ;IS IT A START
MOVSI T1,NDB.SK## ;NO, SET STACK
IORM T1,NDBFEK##(W) ;STORE THE START BIT
PJRST NETWSR ;SEND THE MESSAGE
;SUBROUTINE NCSNID - SEND A NODE ID MESSAGE
;CALL MOVEI J,FEK
; PUSHJ P,NCSNID
;RETURN CPOPJ ;NO CORE ETC
; CPOPJ1 ;SENT
NCSNID: PUSHJ P,SAVE3## ;SAVE THE P'S
SETZB W,F ;NO DDB OR NDB
PUSHJ P,MAKPCB ;GET A PCB
POPJ P, ;NO SPACE
MOVEI T2,^D16 ;MESSAGE SIZE
PUSHJ P,GETZWD ;ALLOCATE THE MESSAGE SPACE
PJRST RMVPCB ;NO SPACE AVAILABLE
MOVEI P2,(T1) ;MAKE A BYTE POINTER
HRLI P2,(POINT 8) ;FOR THE MESSAGE OUTPUT
MOVEM P2,PCBOAD##(U) ;STORE THE BYTE POINTER
SETZ P3, ;CLEAR THE COUNT FIELD
MOVSI T1,^D16 ;GET THE SIZE
MOVEM T1,PCBOCT##(U) ;STORE
;NCT
MOVEI T1,NCT.ID!NCT.SQ ;GET ID FLAGS
PUSHJ P,BI2EBI ;WRITE THE FLAGS
;NCA
MOVEI T1,0 ;NO, ACKS FOR MESSAGE NUMBERS
PUSHJ P,BI2EBI ;WRITE
;NCN
MOVEI T1,0 ;SAME AS ABOVE
PUSHJ P,BI2EBI ;WRITE
;OPD
PUSHJ P,NCSOPD ;SEND THE <NNM><SNM><SID>
MOVSI T1,FK.NID## ;GET NODE ID FLAG
IORM T1,FEKBLK##(J) ;SET FLAG NODE ID SENT
ADDM P3,PCBOCT##(U) ;UPDATE THE COUNT
IFN FTCMSR,<
AOS NCLXTP+NCT.ID
>
AOS (P) ;SKIP RETURN
CONO PI,PIOFF ;NO RACE, "NETWRT" WILL RESTORE PI'S
PJRST FRCWRT ;FORCE WRITE THE MESSSAGE
;SUBROUTINE NCSOPD - GENERATE THE OPTIONAL DATA <NNM><SNM><SID>
;CALL MOVEI U,PCB
; PUSHJ P,NCSOPD
;RETURN CPOPJ
NCSOPD: ;ENTRY
PUSH P,W ;SAVE THE NDB POINTER
MOVEI W,NETNDB## ;GET THE NODE DATA BLOCK
;NNM
HLRZ T1,NDBNNM##(W) ;GET THE NODE NUMBER
PUSHJ P,BI2EBI ;WRITE
;SNM
HLRZ T1,NDBSNM##(W) ;GET THE POINTER TO THE SYSTEM NAME
MOVE T1,(T1) ;GET THE NAME
PUSHJ P,SX2EAS ;WRITE
;SID
HRRZ P1,NDBSID##(W) ;SOFTWARE NAME
PUSHJ P,AS2EAS ;WRITE
HLRZ P1,NDBSID##(W) ;CREATION DATE
POP P,W ;RESTORE THE NDB
PJRST AS2EAS ;WRITE
;SUBROUTINE NCSACK - NCSNAK SEND AN ACK MESSAGE
;CALL MOVEI W,NDB
;PUSHJ P,NCSACK/NCSNAK
;RETURN CPOPJ ;ERROR
; CPOPJ1 ;OK
NCSACK: LDB T1,NDBNCA## ;GET LAST ACK SENT
LDB T2,NDBLAS## ;AND LAST ACK PROCESSED
CAIN T1,(T2) ;IS AN ACK REQUIRED
POPJ P, ;NO, EXIT
NCSAKK: MOVEI T1,NCT.AK ;GET THE ACK TYPE
SKIPA
NCSNAK: MOVEI T1,NCT.NK ;GET THE NACK
PUSHJ P,SAVE3## ;SAVE THE P'
PUSH P,F ;SAVE F
SETZ F, ;CLEAR F NCS MESSAGE
PUSH P,T1 ;SAVE THE TYPE
PUSHJ P,MAKPCB ;MAKE A PCB
JRST [POP P,T1 ;RESTORE T1
PJRST FPOPJ##] ;EXIT
POP P,T1 ;RESTORE THE FLAG
PUSHJ P,NCSHDR ;WRITE THE HEADER
JRST [POP P,F ;RESTORE F
PJRST RMVPCB] ;REMOVE THE PROTOCOL BLOCK
POP P,F ;RESTORE F
PJRST NETWSR ;SEND THE MESSAGE
SUBTTL NCS NUMBER CONTROL MESSAGES
;SUBROUTINE NCNHDR - WRITE THE HEADER FOR NUMBER CONTROL MESSAGES
;CALL MOVEI F,DDB OR 0
; MOVEI W,NDB
; PUSHJ P,NCMHDR
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;OK U=PCB
NCMHDR: ;ENTRY
PUSHJ P,MAKPCB ;MAKE A PCB
POPJ P, ;NO CORE
MOVEI T1,0 ;CONTROL MESSAGE
PUSHJ P,NCSHDR ;OUTPUT THE HEADER
PJRST RMVPCB ;NO CORE, REMOVE THE PCB AND EXIT
MOVEI T1,0 ;NUMBERED CONTROL MESSGE
PUSHJ P,BI2EBI ;DEPOSITE
AOS PCBOCT##(U) ;COUNT THE FIRST BYTE
AOS PCBOCT##(U) ;COUNT THE SECOND BYTE
SETZ P3, ;CLEAR THE COUNT FIELD
IBP P2 ;STEP OVER THE <CNT> FIELD
PJRST CPOPJ1## ;EXIT P2 IS UPDATED
;SUBROUTINE NCSCNT - SEND A CONNECT MESSAGE
;CALL MOVEI F,DDB
; PUSHJ P,NCSCNT
;RETURN CPOPJ ;NO SPACE AVAILABLE
;
;P2=CURRENT OUTPUT BYTE POINTER
NCSCNT::PUSHJ P,SAVJW ;SAVE W AND J
PUSHJ P,SAVE3## ;SAVE P1,P2,P3
HRRZ W,DEVNET##(F) ;GET THE NODE DATA BLOCK
PUSHJ P,NCMHDR ;WRITE NUMBER MESSAGE HEADER
JRST [MOVEI T1,NRTNCE-NODERT
POPJ P,] ;GIVE CAPACITY EXCEEDED ERROR
PUSH P,P2 ;SAVE THE <CNT> POSITION
MOVEI T1,NC.CNT ;CONNECT MESSAGE TYPE
PUSHJ P,BI2EBI ;OUTPUT
;DLA
LDB T1,NETDLA## ;GET THE DESTINATION ADDRESS
PUSHJ P,BI2EBI ;OUTPUT
;SLA
LDB T1,NETSLA## ;GET THE SOURCE PROCESS NUMBER
PUSHJ P,BI2EBI ;OUTPUT
;DPN
HLRZ W,DEVNET##(F) ;GET THE NDT POINTER
LDB T1,NDTOBJ## ;GET THE OBJECT TYPE
IFN FTTSK,<
CAIE T1,OBJ.TK ;CONNECTING A TASK
JRST NCSCN0 ;NO, CONTINUE BELOW
PUSHJ P,TSKCNM## ;YES, CALL TSKSER TO SEND THE NAMES
JRST NCSCN5 ;CONTINUE BELOW
NCSCN0:
>;END FTTSK
PUSHJ P,BI2EBI ;OUTPUT
LDB T1,PUNIT## ;GET THE UNIT NUMBER
PUSHJ P,DPBBIN ;SEND THE UNIT NUMBER
;SPN
MOVEI T1,OBJ.TK ;OBJECT IS A JOB
PUSHJ P,BI2EBI ;OUTPUT
MOVE T1,JBTNAM##(J) ;GET THE PROCESS NAME
PUSHJ P,SX2EAS ;OUTPUT
LDB T1,P2 ;GET THE LAST CHARACTER BACK
TRO T1,200 ;SET THE CONTINUE BIT
DPB T1,P2 ;STORE AGAIN
MOVE T1,JBTPPN##(J) ;GET THE PPN
PUSHJ P,PP2EAS ;OUTPUT AS [P,P]
;MML
NCSCN5: HRRZ W,PCBNDB##(U) ;GET THE NDB POINTER
LDB T1,NDBMML## ;GET THE DDCMP MESSAGE LENGTH
PUSHJ P,BI2EBI ;OUTPUT
;FEA
;DCM
HLRZ W,DEVNET##(F)
LDB T1,NDTDCM## ;GET THE DEVICE MODES POSSIBLE
PUSHJ P,BI2EBI ;WRITE
;RNL
MOVEI T1,0 ;RECORD LENGTH VALIABLE
PUSHJ P,BI2EBI ;WRITE
;DVT
LDB T1,NDTDVT## ;GET THE DEVICE ATTRIBUTES
PUSHJ P,BI2EBI ;WRITE
;CNT
NCSCN1: POP P,T1 ;RESTORE THE <CNT> POINTER
DPB P3,T1 ;STORE THE <CNT>
ADDM P3,PCBOCT##(U) ;UPDATE THE PROTOCOL MESSAGE LENGTH
PUSHJ P,NETWRT ;SEND THE CONNECT
JUMPE F,CPOPJ1## ;EXIT IF CONNECT RESPONSE
LDB T1,NETDLA## ;GET THE DESTINATION LINK
JUMPN T1,CPOPJ1## ;EXIT IF THIS IS A CONFIRM MESSAGE
NCSCN3: PUSHJ P,NETHIB ;WAIT FOR A RESPONSE
LDB T1,NETRSN## ;NO, GET THE REASON BYTE
JUMPN T1,CPOPJ## ;RETURN ERROR CODE IF UNSUCCESSFUL
MOVSI T1,IOSCON ;IF WE AREN'T CONNECTED YET
TDNN T1,DEVIOS(F)
JRST NCSCN3 ;THEN WAIT SOME MORE.
PJRST CPOPJ1## ;GOOD EXIT
;SUBROUTINE NCSDSC - SEND A DISCONNECT MESSAGE
;CALL MOVEI T1,DLA
; MOVEI T2,REASON
; MOVEI F,DDB OR 0 IF REJECT/CONFIRM
; MOVEI W,NDB
; PUSHJ P,NCSDSC
;RETURN CPOPJ ;NO CORE
; CPOPJ1
NCSDSC:: ;ENTRY
PUSHJ P,SAVE3## ;SAVE THE P'2
PUSHJ P,SAVJW ;SAVE J AND W
PUSH P,F ;SAVE THE DDB
SKIPE F ;SKIP IF A REJECT
HRROS DEVNAM(F) ;CLEAR THE DEVICE NAME(UUOCON WON'T CALL AGAIN)
SETZ F, ;SET CONTROL MESSAGE (IE RESPONSE)
HRRI P1,(T1) ;COPY THE DLA
HRLI P1,(T2) ;AND THE REASON
PUSH P,P1 ;SAVE THE FLAGS
PUSHJ P,NCMHDR ;WRITE THE NUMBERED HEADER
JRST [POP P,P1 ;RESTORE P1
JRST FPOPJ] ;EXIT
POP P,P1 ;RESTOE THE FLAGS
PUSH P,P2 ;SAVE THE COUNT BYTE POINTER
MOVEI T1,NC.DSC ;DISCONNECT MESSAGE
PUSHJ P,BI2EBI ;WRITE
;DLA
HRRZ T1,P1 ;GET THE DLA
PUSHJ P,BI2EBI ;WRITE
;SLA
MOVEI T1,0 ;SOURCE LINK = 0
PUSHJ P,BI2EBI ;WRITE
;RSN
HLRZ T1,P1 ;GET THE REASON
PUSHJ P,BI2EBI ;WRITE
;CNT
POP P,T1 ;GET THE COUNT FIELD BYTE POINTER BACK
DPB P3,T1 ;STOE THE COUNT
ADDM P3,PCBOCT##(U) ;STORE THE COUNT
PUSHJ P,NETWRT ;SEND THE MESSAGE
POP P,F ;RESTORE THE DDB
JUMPE F,CPOPJ1## ;EXIT IF CONFIRM OR REJECT
MOVSI T1,IOSCON ;GETT THE CONNECT BIT
ANDCAM T1,DEVIOS(F) ;CLEAR IT DISCONNECT SENT
NCSDS1: PUSHJ P,NETHIB ;WAIT FOR RESPONSE
LDB T1,NETRSN## ;SEE IF HE SENT US A DISCONNECT FIRST
JUMPN T1,NCSDS2 ; IF HE DID, IT QUALIFIES AS CONFIRMATION
MOVSI T1,NT.DSC## ;HAS A DISCONNECT COME IN
TDNN T1,NETSTS##(F) ;FOR US YET?
JRST NCSDS1 ;NO, WAIT LONGER
NCSDS2: PUSHJ P,UNLDDB ;REMOVE THE DDB
PJRST CPOPJ1## ;EXIT
;SUBROUTINE NCSNBN - SEND NEIGHBOR NAME MESSAGE
;CALL PUSHJ P,NCSNBN
;RETURN CPOPJ
; CPOPJ1
NCSNBN: ;ENTRY
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSHJ P,SAVJW ;SAVE J AND W
SETZ F, ;CONTROL MESSAGE
PUSHJ P,NCMHDR ;WRITE NUMBERED HEADER
POPJ P, ;NO CORE
PUSH P,P2 ;SAVE THE LOCATION
MOVEI T1,NC.NBN ;GET HEIGHBOR NAMES
PUSHJ P,BI2EBI ;WRITE
PUSH P,W ;SAVE THE NDB POINTER
MOVEI W,NETNDB## ;GET OUR NDB
MOVE T4,[POINT 18,NDBTOP##(W)] ;SEARCH THE TOPOLOGY TABLE
MOVSI T3,-<^D16> ;TABLE SIZE
;NNM
NCSNB1: ILDB T1,T4 ;GET A NODE NUMBER
JUMPE T1,NCSNB2 ;EMPTY SLOT
LSH T1,-^D8 ;POSITION THE NODE NUMBER
ANDI T1,77 ;ONLY SIX BITS
PUSHJ P,DPBBIN ;WRITE
;LVL
LDB T1,T4 ;GET THE LINK VALUE
ANDI T1,377 ;AND THE LINK VALUE
PUSHJ P,DPBBIN ;SEND
NCSNB2: AOBJN T3,NCSNB1 ;TRY AGAIN
POP P,W ;RESTORE THE TARGET NODE
POP P,T1 ;GET THE POSITION OF <CNT>
DPB P3,T1 ;STORE <CNT>
ADDM P3,PCBOCT##(U) ;UPDATE THE OUTPUT COUNT
MOVSI T1,NDB.NB## ;GET NEIGHBORS SENT
IORM T1,NDBFEK##(W) ;SET IT
PJRST NETWSR ;SEND THE MESSAGE
;SUBROUTINE SETNBN - SET THE BITS TO SEND NEIGHBORS MESSAGES TO ALL
;CALL PUSHJ P,SETNBN
;RETURN CPOPJ
SETNBN: ;ENTRY ON CHANGE OF NEIGHBORS
PUSHJ P,SAVJW ;SAVE J AND W
MOVSI T1,NDB.NB## ;GET NEIGHBORS BIT
MOVEI W,NETNDB## ;START OF NDB'S
SETNB1: HRRZ W,NDBNNM##(W) ;GET THE FIRST NDB LESS OURS
JUMPE W,CPOPJ## ;END OF LIST
ANDCAM T1,NDBFEK##(W) ;CLEAR THE BIT
JRST SETNB1 ;CONTINUE
;SUBROUTINE NCSRCF - REQUEST CONFINURATION MESSAGE
;CALL MOVEI W,NDB
; PUSHJ P,NCSRCF
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;RETURN
NCSRCF: ;ENTRY
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSHJ P,SAVJW ;SAVE J AND W
SETZ F, ;CONTROL MESSAGE
PUSHJ P,NCMHDR ;WRITE A HEADER
POPJ P, ;CAN'T
PUSH P,P2 ;SAVE THE COUNT POSITION
MOVEI T1,NC.RCF ;TYPE REQUEST CONFIGURATION
PUSHJ P,BI2EBI ;SEND
POP P,T1 ;GET THE COUNT POSITION BACK
DPB P3,T1 ;STORE THE COUNT
ADDM P3,PCBOCT##(U) ;UPDATE THE PCB
MOVSI T1,NDB.CF## ;CONFIGURATION BIT
IORM T1,NDBFEK##(W) ;STORE THE BIT
PJRST NETWSR ;SEND THE MESSAGE
;SUBROUTINE NCSCNF - SEND A CONFIGURATION MESSAGE UPON REQUEST
;CALL MOVEI W,NDB
; PUSHJ P,NCSCNF
;RETURN CPOPJ
; CPOPJ1
NCSCNF: ;ENTERY
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSHJ P,SAVJW ;SAVE J W
SETZ F, ;CLEAR THE DDB
PUSHJ P,NCMHDR ;GET A HEADER
POPJ P, ;NO CORE AVAILABLE
PUSH P,P2 ;SAVE THE COUNT POSITION
MOVEI W,NETNDB## ;GET OUR NODE DATA BLOCK
MOVEI T1,NC.CNF ;CONFIGURATION MESSAGE
PUSHJ P,BI2EBI ;SEND
;OBJ
MOVSI P1,-<OBJ.MX+1> ;NUMBER OF DEVICE TYPES
NCSCF1: LDB T1,NETCNF##(P1) ;GET THE COUNT
JUMPE T1,NCSCF2 ;DON'T HAVE ANY
MOVEI T1,(P1) ;GET THE TYPE BACK
PUSHJ P,BI2EBI ;SEND THE DEVICE TYPE
;NDV
LDB T1,NETCNF##(P1) ;DEVICE COUNT
PUSHJ P,BI2EBI ;SEND
;PID
MOVEI T1,0 ;ZERO PID
PUSHJ P,BI2EBI ;SEND
NCSCF2: AOBJN P1,NCSCF1 ;CONTINUE THROUGH THE LIST
POP P,T1 ;RESTORE THE COUNT POSTION
DPB P3,T1 ;STORE THE COUNT
ADDM P3,PCBOCT##(U) ;UPDATE THE PCB COUNT
PJRST NETWSR ;SEND THE MESSAGE
;SUBROUTINE NCSDRQ - SEND A DATA REQUEST
;CALL MOVEI T1,DATA REQUEST COUNT
; MOVEI F,DDB
; PUSHJ P,NCSDRQ
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;REQUEST SENT
NCSDRQ:: ;ENTRY
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSHJ P,SAVJW ;SAVE J AND W
PUSH P,U ;SAVE U (SELF CONTAINED ROUTINE)
HRRZ W,DEVNET##(F) ;GET THE NDB
PUSH P,T1 ;SAVE THE DRQ
PUSHJ P,NCMHDR ;WRITE THE HAEDER
JRST [POP P,T1 ;RESTORE THE DRQ
PJRST UPOPJ##];EXIT
POP P,P1 ;RESTORE THE DRQ
PUSH P,P2 ;SAVE THE COUNT POINTER
MOVEI T1,NC.DQR ;DATA REQUEST
PUSHJ P,BI2EBI ;WRITE
;DLA
LDB T1,NETDLA## ;GET THE DESTINATION LINK ADDRESS
PUSHJ P,BI2EBI ;WRITE
;DQR
MOVEI T1,(P1) ;GET THE DQR
PUSHJ P,BI2EBI ;WRITE
;CNT
POP P,T1 ;GET THE COUNT POINTER BACK
DPB P3,T1 ;STORE THE COUNT
ADDM P3,PCBOCT##(U) ;AND IN THE PCB
PUSHJ P,NETWRT ;SEND THE MESSAGE
PJRST UPOPJ1## ;SKIP EXIT
;SUBROUTINE NCSCTL - SEND A STATION CONTROL MESSAGE
;CALL MOVEI W,NDB
; MOVE T1,[XWD COUNT,ADDR]
; PUSHJ P,NCSCTL
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;MESSAGE SENT
NCSCTL: ;ENTRY
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSHJ P,SAVJW
PUSH P,T1 ;SAVE THE ARGUMENT
NCSCT1: SETZ F, ;NCS MESSAGE
PUSHJ P,NCMHDR ;WRITE A NUMBERED MESSAGE HEADER
JRST TPOPJ## ;EXIT
HLRZ T1,(P) ;GET THE USER COUNT SIZE
HRRZM T1,PCBOC2##(U) ;STORE THE COUNT
ADDI T1,1 ;<CNT><TYP>
LSHC T1,-7 ;GET LOW POSITION
ROT T2,7 ;FIRST
TRO T2,200
DPB T2,P2 ;STORE
IDPB T1,P2 ;STORE HIGH HALF
ADDI P3,1 ;INCREMET THE COUNT FIELD
MOVEI T1,NC.CTL ;STATION CONTROL TYPE
PUSHJ P,BI2EBI ;SEND
HLRZ T2,(P) ;GET THE # OF BYTES
ADDI T2,3 ;ROUND UP
LSH T2,-2 ;CONVERT TO WORDS
PUSHJ P,GETZWD ;ALLOCATE A BUFFER
JRST TPOPJ## ;ERROR RETURN
HRLI T1,(POINT 8) ;MAKE A BYTE POINTER
MOVEM T1,PCBOA2##(U) ;STORE IN THE PCB
HLRZ T3,(P) ;GET THE BYTE COUNT
ADDI T3,3 ;ROUND UP
LSH T3,-2 ;INTO WORDS
HRLM T3,PCBOC2##(U) ;STORE
ADD T3,PCBOA2##(U) ;POINT TO THE END OF THE BUFFER
SUBI T3,1 ;LESS ONE
POP P,T1 ;GET THE USER ADDRESS
IFN FTKA10,<
ADDI T1,(R) ;POINT TO FIRST NEW IN USER'S AREA
>
HRLS T1 ;PUT IN THE LEFT HALT
HRR T1,PCBOA2##(U) ;GET THE BUFFER ADDRESS
EXCTUX <BLT T1,(T3)> ;MODE THE DATA
ADDM P3,PCBOCT##(U) ;STORE THE COUNT
PJRST NETWSR ;SEND THE MESSAGE
SUBTTL MEMORY CONTROL ROUTINES
;SUBROUTINE SLPZWD - GET WORDS FROM MONITOR FREE CORE AND SLEEP UNTIL AVAILABLE
;CALL MOVEI T2,#WORDS
; PUSHJ P,SLPZWD
;RETURN CPOPJ ;WHEN AVAILABLE
SLPZWD:: ;ENTRY
PUSHJ P,GETZWD ;TRY TO ALLOCATE
SKIPA ;NOT AVAILABLE
POPJ P, ;RETURN
PUSHJ P,NETSLP ;SLEEP FOR TWO SECONDS
JRST SLPZWD
;SUBROUTINE GETZWD - GET A BLOCK OF MONITOR FREE CORE AND ZERO
;CALL MOVEI T2,#WORDS
; PUSHJ P,GETZWD
;RETURN CPOPJ ;NO CORE AVAILABLE
; CPOPJ1 ;T1=ADDRESS
GETZWD: PUSH P,T2 ;SAVE THE NUMBER OF WORDS
HLRE T1,FREPTR## ;GET LENGTH OF FREE CORE MAP
MOVNS T1
IMULI T1,^D36 ;MAKE #4 WORD BLOCKS (=1/4 FREE CORE TOTAL)
CAML T1,%NTCOR ;DON'T USE MORE THAN 1/4 OF FREE CORE
PUSHJ P,GETWDS## ;ALOCATE THE SPACE
PJRST T2POPJ## ;NO, SPACE AVAILABLE
SETZM (T1) ;CLEAR THE FIRST WORD
MOVE T2,(P) ;GET THE NUMBER OF WORDS
ADDM T2,%NTCOR ;ACCOUNT FOR CORE USED
MOVEM T1,(P) ;SAVE THE STARTING ADDRESS
ADDI T2,-1(T1) ;POINT TO THE END OF THE LIST
HRLI T1,1(T1) ;MAKE A BLT POINTER
MOVSS T1 ;FROM,,TO
BLT T1,(T2) ;CLEAR THE BLOCK
IFN FTCMSR,<
MOVE T1,%NTCOR ;IF WE NOW ARE USING MORE
CAMLE T1,%NTMAX ; CORE THAN EVER BEFORE
MOVEM T1,%NTMAX ; RECORD FOR PRYING EYES
>
PJRST TPOPJ1## ;RESTORE THE ADDRESS AND EXIT
;SUBROUTINE GIVZWD - RETURN MONITOR FREE CORE
;CALL MOVEI T1,#WORDS
; MOVEI T2,ADDRESS
; PUSHJ P,GIVZWD
;RETURN CPOPJ
GIVZWD: ;ENTRY
PUSH P,T1 ;SAVE NUMBER OF WORDS
MOVNS T1 ;NEGATE
ADDB T1,%NTCOR ;REDUCE CORE USED
SKIPGE T1 ;CHECK RESULT
STOPCD TPOPJ##,DEBUG,CWN,;++CORE ALLOCATION WENT NEGATIVE
POP P,T1 ;RESTORE WORD COUNT
PJRST GIVWDS## ;RETURN THE CORE
;SUBROUTINE SAVJW SAVE AC'S W AND J
;CALL PUSHJ P,SAVJW
;RETURN CPOPJ
SAVJW:: EXCH J,(P) ;SAVE J AND GET THE RETURN
PUSH P,W ;SAVE W
MOVEM J,1(P) ;SAVE THE RETURN
MOVE J,-1(P) ;RESTORE J
PUSHJ P,@1(P) ;RETURN
SKIPA ;SKIP RETURN NO
AOS -2(P) ;SKIP YES
POP P,W ;RESTORE W
PJRST JPOPJ## ;RESTORE J AND EXIT
;SUBROUTINE SVEVM - SAVE THE JOB EVM AND RESTORE ON POPJ
;CALL PUSHJ P,SVEVM
;RETURN CPOPJ
IFE FTKI10!FTKL10,<SVEVM==CPOPJ##>
IFN FTKI10!FTKL10,<
SVEVM::SKIPN DEVEVM(F) ;ANY EVM
POPJ P, ;NO RETURN
PUSHJ P,RTEVM## ;YES, RETURN THE EVM
POP P,(P) ;PUT THE RETURN ON THE END OF THE STACK
PUSHJ P,@1(P) ;RETURN TO THE CALLER
PJRST RSTEVM## ;NON-SKIP RESTORE EVM
AOS (P) ;SKIP RETURN
PJRST RSTEVM## ;RESTORE EVM AND EXIT
>
SUBTTL COMMON SUBROUTINES TO CONVERT EXTENSIBLE ASCII/BINARY
;SUBROUTINE EAS2SX CONVERT EXTENSIBLE ASCII TO SIXB
;CALL MOVEI P1,[INPUT POINTER]
; PUSHJ P,EAS2SX
;RETURN CPOPJ ;T1=SIXIT
EAS2SX::MOVE T2,[POINT 6,T1] ;GET BYTE POINTER
SETZB T1,T4 ;CLEAR OUTPUT
EAS2S1: SOJL P4,CPOPJ## ;EXIT IF NO MORE DATA
ILDB T3,P1 ;GET THE BYTE
TRZN T3,200 ;CONTINUE BIT
SETO T4, ;NO, SET FLAG
TRNE T3,140 ;MAKE SURE ASCII BEFOR SUBI
SUBI T3,40 ;CONVERT TO SIXBIT
TRNN T3,177 ;CHECK FOR A BLANK CHARACTER
JUMPE T1,EAS2S2 ;AND A LEADING BLANK
CAIE T3,'[' ;CHECK TO [XXX,XXX]
CAIN T3,']' ;AND EXIT
POPJ P, ;IF FOUND
CAIN T3,',' ;ALSO A COMMA
POPJ P, ;WILL EXIT
TLNE T2,(77B5) ;END OF WORD
IDPB T3,T2 ;STORE WORD
EAS2S2: JUMPGE T4,EAS2S1 ;NO CONTINUE
POPJ P, ;RETURN
;SUBROUTINE SX2EAS CONVERT SIXBIT TO EXTENSIBLE ASCII
;CALL MOVE T1,[SIXBIT /.../]
; MOVE P2,[OUTPUT BYTE POINTER]
; PUSHJ P,SX2EAS
;RETURN CPOPJ ;P3 COUNTED UP
SX2EAS::SKIPE T2,T1 ;COPY THE SIXBIT NAME
SX2EA1: SETZ T1, ;CLEAR THE OUTPUT AC
LSHC T1,6 ;GET A SIXBIT CHARACTER
ADDI T1,240 ;CONVERT TO ASCII WITH CONTINUE BIT
IDPB T1,P2 ;STORE CHARACTER
ADDI P3,1 ;COUNT THE CHARACTER
JUMPE T2,CLRBT8 ;EXIT AND CLEAR CONTINUE BIT
JRST SX2EA1 ;COUNT AND CONTINUE
;SUBROUTINE AS2EAS CONVERT ASCIZ TO EXTENSIBLE ASCII
;CALL MOVE P1,[INPUT BYTE POINTER] ASCII 7
; MOVE P2,[OUTPUT BYTE POINTER] EXTENSIBLE ASCII 8
; PUSHJ P,AS2EAS
;RETURN CPOPJ ;P3 UPDATED WITH CHARACTER COUNT
AS2EAS::TLNN P1,-1 ;IS THERE A BYTE POINTER
HRLI P1,(POINT 7) ;NO, SUPPLY ONE
AS2EA1: ILDB T1,P1 ;GET AN ASCII CHARACTER
JUMPE T1,CLRBT8 ;JUMPE IF END
TRO T1,200 ;SETHIGH ORDER BIT
IDPB T1,P2 ;STORE 8 BIT BYTE
AOJA P3,AS2EA1 ;COUNT CHARACTER TRY AGAIN
CLRBT8: LDB T1,P2 ;GET LAST STORED CHARACTER BACK
TRZ T1,200 ;CLEAR THE CONTINUE BIT
DPB T1,P2 ;STORE CHARACTER
POPJ P, ;RETURN
;SUBROUTINE EAS2AS CONVERT AN EXTENSIBLE ASCII STRING TO ASCIZ
;CALL MOVE P1,[INPUT BYTE POINTER]
; MOVE P2,[OUTPUT BYTE POINTER]
; PUSHJ P,EAS2AS
;EXIT
EAS2AS::HRLI P2,(POINT 7) ;MAKE A BYTE POINTER
MOVEI T2,^D37 ;ALLOW A MAX CHARACTER COUNT
EAS2A1: SOJLE P4,CPOPJ## ;EXIT IF NO MORE
ILDB T1,P1 ;GET AN 8 BIT CHARACTER
IDPB T1,P2 ;STORE A SEVEN BIT CHARACTER
TRNE T1,200 ;IS CONTINUE BIT ON
SOJG T2,EAS2A1 ;YES, CONTINUE
SETZ T1, ;SET UP A NULL
IDPB T1,P2 ;STORE THE NULL
POPJ P, ;RETURN
;SUBROUTINE BI2EBI CONVERT A BINARY NUMBER TO EXTENSIBLE BINARY
;CALL MOVE T1,[A BINARY NUMBER]
; MOVE P2,[OUTPUT BYTE POINTER] 8 BIT
; PUSHJ P,BI2EBI,OCT2EBI,DE2EBI
;RETURN CPOPJ ;P3 UPDATED
BI2EBI::CAIG T1,177 ;GREATER THAN 177
JRST DPBBIN ;NO OUTPUT
LSHC T1,-7 ;SHIFT OFF THE BITS
ROT T2,7 ;SAVE IN T2
TRO T2,200 ;SET CONTINUE BIT
IDPB T2,P2 ;STORE IN MESSAGE
AOJA P3,BI2EBI ;CONTINUE
DC2EAS: SKIPA T3,[^D10] ;DECIMAL CONVERSION
OC2EAS: MOVEI T3,^D8 ;OCTAL CONVERSION
RX2EBI: IDIVI T1,(T3) ;SEPERATE AGAIN
HRLM T2,(P) ;STORE THE BYTE
SKIPE T1 ;ANY LEFT NOW
PUSHJ P,RX2EBI ;YES, TRY AGAIN
HLRZ T1,(P) ;GET THE LAST DIGIT BACK
ADDI T1,"0" ;NO CONVERT TO ASCII
DPBEAS: TRO T1,200 ;SET THE CONTINUE BIT
DPBBIN: ADDI P3,1 ;COUNT
IDPB T1,P2 ;NO STORE THE DIGIT
POPJ P, ;RETURN
;SUBROUTINE EBI2BI TO CONVER EXTENSIBLE BINARY TO BINARY
;CALL MOVE P1,[INPUT BYTE POINTER
; PUSHJ P,EBI2BI
;RETURN CPOPJ ;T1=BINARY NUMBER
EBI2BI::SETZ T1, ;CLEAR THE OUTPUT
MOVE T3,[POINT 7,T1,35] ;OUTPUT BYTE POINTER
EBI2B1: SOJL P4,CPOPJ## ;EXIT IF THE END OF DATA
ILDB T2,P1 ;GET THE NEXT CHARACTER
DPB T2,T3 ;STORE THE NEXT DIGIT
TRNN T2,200 ;IS THE NUMBER EXTENDED
POPJ P, ;NO, EXIT
ADD T3,[7B5] ;YES, STEP LEFT ONE 7 BIT BYTE
JRST EBI2B1 ;CONTINUE
;SUBROUTINE PP2EAS - OUTPUT A PPN IN EXTENSIVE ASCII
;CALL MOVE T1,[PPN]
; PUSHJ P,PP2EAS
;RETURN CPOPJ
PP2EAS::PUSH P,T1 ;SAVE THE PPN
MOVEI T1,"[" ;OPEN BRACKET
PUSHJ P,DPBEAS ;OUTPUT
HLRZ T1,(P) ;GET THE PROGRAMMER NUMBER
PUSHJ P,OC2EAS ;OUTPUT
MOVEI T1,"," ;SEPERATOR
PUSHJ P,DPBEAS ;OUTPUT
POP P,T1 ;RESTORE THE STACK GET PROGRAMMER #
HRRZS T1 ;RT HALF
PUSHJ P,OC2EAS ;OUTPUT
MOVEI T1,"]" ;CLOSING BRACKET
PUSHJ P,DPBEAS ;OUTPUT
PJRST CLRBT8 ;CLEAR THE LAST BIT
;SUBROUTINE EAS2PP - INPUT A PROCESS ANEM AND UIC
;CALL PUSHJ P,EAS2PP
;RETURN CPOPJ
IFN FTTSK,<
EAS2PP:: ;ENTRY
PUSHJ P,EAS2SX ;GET THE SIXBIT NAME
PUSH P,T1 ;SAVE
SETZ T2, ;CLEAR THE PPN WORD
CAIE T3,'[' ;DOES A PPN FOLLOW
PJRST TPOPJ## ;NO EXIT T1=NAME T2=PPN
PUSHJ P,EAS2SX ;GET THE PROJECT NUMBER
PUSHJ P,CVTOCT## ;CONVERT TO OCTAL
SETZ T1, ;ILLEGAL SET TO ZERO
PUSH P,T1 ;SAVE THE PROJECT NUMBER
PUSHJ P,EAS2SX ;GET THE PROGRAMMER NUMBER
PUSHJ P,CVTOCT## ;CONVERT TO OCTAL
SETZ T1, ;ILLEGAL
HRL T1,(P) ;GET THE PROGRAMMER NUMBER BACK
MOVE T2,T1 ;COPY TO T2
POP P,(P) ;REMOVE SCRATCH FROM THE STACK
PJRST TPOPJ## ;EXIT T1=NAME T2=PPN
>;END FTTSK
SUBTTL NETINI - INITILIZATION/ONCE A SECOND CODE
;NETINI CALLED BY ONCE ONLY
NETINI::
PUSH P,J ;SAVE J
HRRZ J,NETFEK ;FIRST FEK ADDRESS
NETIN1: HRRZS FEKBLK(J) ;CLEAR THE KONTROLLER FLAGS
XCT FEKONC##(J) ;CALL THIS CNTROLLER
HRRZ J,FEKBLK##(J) ;GET THE NEXT KONTROLLER
JUMPN J,NETIN1 ;END OF LIST ... CONTINUE
PJRST JPOPJ## ;RESTORE J AND EXIT
;CALLED ONCE A SECOND
NET2ND::PUSHJ P,SAVJW ;SAVE J AND W ETC
IFN FTCMSR,<
MOVE T1,%NTCOR ;COMPUTE AVERAGE BUFFER USAGE
IMULI T1,^D10000-TIMFAC ;EACH SECOND COUNTS THIS MUCH
MOVE T2,%NTAVG
MULI T2,TIMFAC ;MAKE ROOM FOR IT IN THE OLD AVERAGE
DIVI T2,^D10000
ADD T1,T2
MOVEM T1,%NTAVG ;AVERAGE FOR THIS SECOND
>
NETFEK: MOVEI J,0 ;ADDRESS IS MODIFIED BY LINK 10
.LNKEND FEKLNK,.-1 ;START OF LINK
NET2N1: XCT FEKSEC##(J) ;CALL THE CONTROLLER ROUTINE
SKIPL T1,FEKBLK##(J) ;IS HTHIS KONTROLLER ONLINE
JRST NET2N4 ;NO, SKIP
TLNN T1,FK.NID## ;NODE ID SENT
PUSHJ P,NCSNID ;NO, SEND IT
JFCL ;ERROR NO CORE (SEND NEXT TIME)
SKIPGE FEKBSI##(J) ;INPUT BUSY
PUSHJ P,NETRDD ;NO, MAKE IT BUSY
NET2N4:
HRRZ J,FEKBLK##(J) ;GET THE NEXT CONTROLLER
JUMPN J,NET2N1 ;CONTINUE
;SCAN THE NDB'S
MOVEI W,NETNDB## ;STARTING NODE
NET2N2: MOVE J,NDBFEK##(W) ;IS THIS NODE STARTED
TRNN J,-1 ;ANY FEK ASSIGNED
JRST NET2N5 ;NO, IGNORE
JUMPL J,NET2N3 ;IS THE NODE STARTED
PUSHJ P,NCSSTR ;NO, SEND A START
JFCL ;NEXT TIME
NET2N3: TLNN J,NDB.SK## ;STACK SENT OR RECEIVED
JRST NET2N5 ;NO, WAIT FOR THE STACK
TLNN J,NDB.CF## ;CONFIGURATION REQUEST
PUSHJ P,NCSRCF ;NO SEND IT
JFCL ;TRY LATER
TLNN J,NDB.NB## ;NEED NEIGHBORS
PUSHJ P,NCSNBN ;YES, SEND IT
JFCL ;LATER
MOVSI T2,-1 ;INCREMENT COUNTER TO TIME OUT BOOT REQUESTS
ADDB T2,SCBRQB##(W) ; IN CASE NETLDR DIES
JUMPGE T2,NET2N5 ;NOT YET
ANDI T2,-1 ;ISOLATE ADDRESS
JUMPE T2,NET2N5 ;NOTHING THERE TO START WITH
HLRZ T1,(T2) ;GET LENGTH
PUSHJ P,GIVZWD ;RELEASE SPACE
SETZM SCBRQB##(W) ;RELEASE RESOURCE
NET2N5: HRRZ W,NDBNNM##(W) ;NEXT NODE
JUMPN W,NET2N2 ;YES, TRY AGAIN
POPJ P, ;RETURN TO "CLOCK1"
SUBTTL NETCTC - CALL ON RESET OR ^C^C AND NOT CCON/CON
NETCTC:: ;CALLED BY UUOCON
PUSHJ P,SAVJW ;SAVE J AND W
;CHECK FOR REMOTE DIALER IN USE
HLRZ T1,DILLDB ;GET THE JOB NUMBER (IF ANY)
ANDI T1,777 ;ONLY NONE BITS WORTH
CAIN T1,(J) ;IS THIS JOB
SETZM DILLDB ;YES, CLEAR THE DIALER
;CLEAR THE STATION CONTROL DEVICE IF THERE
NETCT0: MOVSI T1,NSHF!NSWP ;MUST BE LOCKED IN CORE TO HAVE THE DEVICE
TDNN T1,JBTSTS##(J) ;IS IT
JRST NETCT3 ;NONE
MOVEI W,NETNDB## ;GET THE START ON THE NDB CHAIN
NETCT1: SKIPN T1,SCBCTL##(W) ;IS STATION CONTROL BUSY
JRST NETCT2 ;NO, CONTINUE
HLRZS T1 ;GET THE JOB NUMBER FOR COMPARE
CAIN T1,(J) ;DOES THIS JOB HAVE THE DEVICE
SETZM SCBCTL##(W) ;YES, CLEAR THE DEVICE
NETCT2: HRRZ W,NDBNNM##(W) ;GET THE NEXT STATION POINTER
JUMPN W,NETCT1 ;CONTINUE UNLESS THE END OF NDB
;HERE TO CHECK FOR PENDING CONNECT/DISCONNECT MESSAGES
NETCT3:
PUSHJ P,FNDPDS## ;FIND THE PDB FOR THE JOB
PUSH P,F ;SAVE THE DDB POINTER
HLRZ F,.PDNET##(W) ;GET THE POSSIBLE DDB POINTER
JUMPE F,NETCT4 ;NONE
HRRZS .PDNET##(W) ;CLEAR THE POINTER
MOVE S,DEVIOS(F) ;IF THE DEVICE NEVER GOT CONNECTED
TLNN S,IOSCON ;OR IS BEING DISCONNECTED,
PUSHJ P,UNLDDB ;UNLINK THE DDB
NETCT4: JRST FPOPJ## ;RESTORE F AND EXIT
SUBTTL FEKINT INTERRUPT LEVEL PROCESSINT
;CALL MOVE J,[XWD FLAGS,FEK]
; PUSHJ P,FEKINT##
;RETURN CPOPJ ;CALLING ROUTINE MUST DISMISS THE INTERRUPT
FEKINT:: ;ENTRY ON INTERRUPT
TRNN J,-1 ;MUST HAVE AN ADDRESS
JRST FEKINX ;NO ERROR
TLNE J,FI.IN## ;INPUT INTERRUPT
JRST INPINT ;YES
TLNE J,FI.OUT## ;OUTPUT INTERRUPT
JRST OUTINT ;YES
TLNE J,FI.DWN## ;DID THE KONTROLER GO DOWN
JRST KONDWN ;YES, PROCESS DOWN
TLNE J,FI.DAE## ;DAEMON ERROR REPORT
JRST DAEINT ;YES
FEKINX: STOPCD CPOPJ##,DEBUG,IFU,;++INTERRUPT FLAG UNRECONIZED
;HERE TO PROCESS A DAEMON REQUEST
DAEINT: ;ENTRY FROM INTERRUPT LEVEL
HRRI T1,50 ;GET THE FLAG
HRLI T1,FEKERR##(J) ;AND THE POINTER TO THE ERROR TABLE
PUSH P,J ;SAVE J
PUSHJ P,DAEEIM## ;CALL DAEMON
JFCL ;IGNORE ERRORS
PJRST JPOPJ## ;RESTORE THE FEK AND RETURN
;HERE WHEN A KONTROLLER GOES DOWN
KONDWN: PUSHJ P,SAVE1## ;SAVE P1
HRRZS FEKBLK##(J) ;CLEAR THE FLAGS
;HERE TO CHECK THE INPUT QUEUE
SKIPGE FEKBSI##(J) ;IS THERE AN INPUT REQUEST
JRST KONDW1 ;NO,
HRRZ U,FEKIAD##(J) ;YES, GET THE PCB
PUSHJ P,RMVPCB ;REMOVE THE FEK
KONDW1: SETOM FEKBSI##(J) ;CLEAR BUSY
SETZM FEKIAD##(J) ;CLEAR PCB POINTER
;HERE TO CHECK THE OUTPUT QUEUE
SKIPGE FEKBSO##(J) ;IS OUTPUT BUSY
JRST KONDW3 ;NO
HRRZ P1,FEKOAD##(J) ;GET THE PCB POINTER
KONDW2: MOVEI U,(P1) ;COPY THE ADDRESS
HRRZ P1,PCBBLK##(U) ;GET THE NEXT PCB
PUSHJ P,RMVPCB ;REMOVE THE PCB
JUMPN P1,KONDW2 ;CONTINUE IF ANOTHER PCB
KONDW3: SETOM FEKBSO##(J) ;CLEAR BUSY
SETZM FEKOAD##(J) ;CLEAR THE PCB POINTER
;HERE TO CHECK FOR NODES CONNECTED TO THE KONTROLLER
KONDW7: MOVEI P1,NETNDB## ;GET THE START OF THE NDB CHAIN
KONDW4: HRRZ W,NDBNNM##(P1) ;SKIP THE PROTOTYPE
JUMPE W,KONDW6 ;END OF LIST
HRRZ T1,NDBFEK##(W) ;GET THE FEK POINTER
CAIE T1,(J) ;IS THIS NODE CONNECTED
JRST KONDW5 ;NO, STEP THE CHAIN
PUSHJ P,RMVNDB ;REMOVE THE NDB
JRST KONDW7 ;TRY AGAIN
KONDW5: MOVEI P1,(W) ;COPY THE POINTE
JRST KONDW4 ;TRY AGAIN
KONDW6: POPJ P, ;DISMISS THE INTERRUPT
SUBTTL OUTINT - OUTPUT INTERRUPT PROCESSOR FOR ALL FEK'S
;SUBROUTINE OUTINT - OUTPUT INTERRUPT
;CALL MOVE J,[XWD FLAGS,FEK]
; PUSHJ P,OUTINT
;RETURN CPOPJ
OUTINT: ;ENTRY
PUSH P,U ;SAVE U
PUSH P,W ;SAVE W
HRRZ U,FEKOAD##(J) ;GET THE PCB
MOVE T1,PCBBLK##(U) ;GET THE FLAGS AND POINTER
TLNE T1,PCB.OF## ;DID DESTINATION GO OFFLINE?
TLZ T1,PCB.UN## ;YES, DON'T LET PCB.UR!PCB.NM DO THEIR THING
PUSH P,T1 ;SAVE PCB.UR FLAG FOR OUTIN4
HRRZM T1,FEKOAD##(J) ;STORE THE NEXT PCB
HLLZS PCBBLK##(U) ;CLEAR THE LINK POINTER
HLRZ F,PCBDDB##(U) ;GET THE DDB IF ANY
HRRZ W,PCBNDB##(U) ;GET THE NODE DATA BLOCK
JUMPGE T1,OUTIN4 ;UNNUMBERED DO NO QUEUE
LDB T1,PCBMSN## ;GET THE NUMBER OF THE MESSAGE SENT
DPB T1,NDBLMS## ;SAVE AS LAST SENT
HRRZ T2,NDBQUE##(W) ;GET THE OUTPUT QUEUE POINTER
JUMPN T2,OUTIN1 ;JUMP IF QUEUE NOT EMPTY
HRRM U,NDBQUE##(W) ;YES, THIS IS THE ONLY PCB
JRST OUTIN2 ;CONTINUE
OUTIN1: MOVEI T1,(T2) ;SEARCH FOR THE END OF THE QUEUE
HRRZ T2,PCBBLK##(T1) ;GET THE NEXT ENTRY
JUMPN T2,OUTIN1 ;CONTINUE TO THE END
CAIN U,(T1) ;CHECK FOR LINK TO SELF
STOPCD .+1,DEBUG,LTS, ;LINK TO SELF
HRRM U,PCBBLK##(T1) ;LINK TO THE END
OUTIN2:
OUTIN3: SKIPA ;NUMBERED MESSAGE
OUTIN4: PUSHJ P,RMVPCB ;NO REMOVE THE PCB
SOSGE FEKBSO##(J) ;ANOTHER MESSAGE TO SEND?
JRST OUTIN7 ;NO, CLEAN UP AFTER LAST MESSAGE
MOVE U,FEKOAD##(J) ;LOOK AT CURRENT MESSAGE
MOVE T1,PCBBLK##(U) ;GET FLAGS AND NEXT PCB
TLNN T1,PCB.OF## ;IF DESTINATION IS STILL ONLINE,
JRST OUTIN6 ; SEND IT THERE
HRRM T1,FEKOAD##(J) ;DELINK USELESS MESSAGE
JRST OUTIN4 ;DISCARD IT AND TRY AGAIN
OUTIN6: XCT FEKWRT##(J) ;SEND IT
OUTIN7: POP P,T1 ;GET PCBBLK BACK
TLNN T1,PCB.UR## ;WAS THERE USER DATA?
JRST OUTIN5 ;NOPE, RETURN
MOVEI T1,NDPODN## ;GET OUTPUT DONE INDEX
HLRZ T2,DEVNET(F) ;GET NDT ADDRESS
PUSHJ P,@NDTNDP##(T2) ;CALL THE DEVICE SERVICE ROUTINE
OUTIN5: POP P,W ;RESTORE W
PJRST UPOPJ## ;RESTORE U AND DISMISS THE INTERRUPT
SUBTTL NETWRT - SEND A MESSAGE TO THE FRONT END KONTROLLER FEK
;SUBROUTINE NETWRT - SEND A MESSAGE
;CALL MOVEI F,DDB OR 0 IF A NCL MESSAGE
; MOVEI U,PCB
; PUSHJ P,NETWRT ;CALLED AT INTERRUPT OR UUO LEVEL
;RETURN CPOPJ ;ALWAYS
NETWSR: AOS (P) ;SKIP RETURN
NETWRT:: ;ENTRY
PUSHJ P,SAVJW ;SAVE J/W
HRRZ W,PCBNDB##(U) ;GET THE NDB POINTER
HRRZ J,NDBFEK##(W) ;GET THE FEK POINTER
IFN FTCMSR,<
MOVE T4,PCBOAD(U) ;GET ADDRESS OF MESSAGE
HRLI T4,(POINT 8,0,7) ;POINT TO NCT
LDB T1,T4 ; AND GET IT
ANDI T1,NCT.TP ;ISOLATE MESSAGE TYPE
AOS NCLXTP(T1) ;COUNT IT
JUMPN T1,NETWR2 ;WE'RE DONE IF THIS IS UNNUMBERED CONTROL
ADD T4,[<POINT 8,1,15>-<POINT 8,0,7>] ;POINT TO DLA
LDB T1,T4 ; AND GET IT
JUMPN T1,NETWR1 ;NON-ZERO MEANS DATA MESSAGE
IBP T4 ;SKIP CNT
ILDB T1,T4 ;GET NUMBERED MESSAGE TYPE
CAIG T1,NC.MAX ;IN RANGE?
AOS NCLXMT(T1) ;YES, COUNT IT
JRST NETWR2 ;ALL DONE, OKAY TO SEND
NETWR1: MOVE T1,PCBOCT(U) ;GET LENGTH OF ENTIRE MESSAGE
ADD T1,PCBOC2(U) ;INCLUDING USER DATA, IF ANY
MOVEI T1,-6(T1) ;DISCARD PROTOCOL OVERHEAD
CAIGE T1,1_<DLHSIZ-1> ; IN RANGE OF TABLE?
JFFO T1,.+2 ;YES, GET APPROPRIATE RANGE
TDZA T1,T1 ;OUT OF RANGE, INCREMENT ENTRY 0
MOVNI T1,-^D36(T2) ;MAKE ASCENDING ENTRIES MEAN LONGER LENGTHS
AOS NCLXDL(T1) ; AND RECORD IT
>
NETWR2: CONO PI,PIOFF ;TURN OF THE PI SYS
;ASSIGN MESAGE NUMBERS HERE
;NCA
MOVE T4,PCBOAD##(U) ;GET THE OUTPUT POINTER
HRLI T4,(POINT 8,0,31) ;POINT TO THE NCA/NCN FIELDS
LDB T1,NDBNCA## ;GET THE LAST MESSAGE ACK'ED
DPB T1,NDBLAS## ;SAVE AS LAST ACK
DPB T1,T4 ;STORE THE ACK NUMBER
;NCN
LDB T1,NDBLMA## ;GET THE LAST MESSAGE NUMBER ASSIGNED
SKIPGE PCBBLK##(U) ;NUMBERED MESSAGE
ADDI T1,1 ;YES, UPATE THE COUNT
DPB T1,NDBLMA## ;STORE AS LAST ASSIGNED
IDPB T1,T4 ;STORE THIS MESSAGE NUMBER
DPB T1,PCBMSN## ;SAVE THE MESSAGE NUMBER OF THIS PCB
FRCWRT: SKIPL FEKBLK##(J) ;DID THE KONTROLLER DIE WHILE WE WEREN'T LOOKING
JRST [CONO PI,PI.ON ;IF SO, RE-ENABLE INTERRUPTS
JRST RMVPCB] ; AND DESTROY THIS MESSAGE
AOSE FEKBSO##(J) ;IS THE KONTROLLER BUSY
JRST NETWQU ;YES, MUST QUEUE THE REQUEST
HRRZM U,FEKOAD##(J) ;STORE THE PCB POINTER
CONO PI,PION ;BACK ON
XCT FEKWRT##(J) ;CALL THE KONTROLLER
POPJ P, ;RETURN
;HERE TO QUEUE A REQUEST FOR A FEK
;NCL MESSAGE GO TO THE BACK OF THE QUEUE
;USER MESSAAGE GO TO THE BACK OF THE QUEUE
NETWQU: HRRZ T2,FEKOAD##(J) ;GET THE CURRENT PCB POINTER
NETWQ1: MOVEI T1,(T2) ;STEP DOWN THE QUEUE LIST
HRRZ T2,PCBBLK##(T1) ;GET THE NEXT ENTRY
JUMPN T2,NETWQ1 ;END OF LIST
HRRM T2,PCBBLK##(U) ;LINK THE NEW PCB
HRRM U,PCBBLK##(T1) ;TO LAST OR FIRST IN THE QUEUE
PJRST ONPOPJ## ;TURN THE INTERRUPT SYSTEM ON RETURN
SUBTTL NETHIB/NETWAK - HIBERNATE AND SLEEP ROUTINE FOR JOB ON THE NET
;SUBROUTINE NETHIB - PUT THE JOB IN THE HIBER STATE
;CALL MOVEI F,DDB
; PUSHJ P,NETHIB
;RETURN CPOPJ ;WHEN AWAKEN BY NETWAK
NETHIB:: ;ENTRY
SKIPN F ;MUST HAVE A DDB
STOPCD CPOPJ##,STOP,FFU,;++F FOULED UP
PUSHJ P,SAVJW ;SAVE W AND J
PUSHJ P,SVEVM ;SAVE ANY EVM
LDB J,PJOBN## ;GET THE JOB NUMBER
PUSHJ P,FNDPDS## ;GET THE PDB
HRLM F,.PDNET(W) ;STORE THE DDB POINTER IN CASE OF RESET(^C^C)
MOVEI T1,EV.NET ;GET REASON FOR EVENT WAKE
PUSHJ P,ESLEEP## ;WAIT
HRRZ W,JBTPDB##(J) ;GET THE PDB BACK
HRRZS .PDNET##(W) ;CLEAR THE POINTER
POPJ P, ;YES, EXIT TO CALLER
;SUBROUTINE NETWAK - WAKE THE JOB UP PUT TO SLEEP BY NETHIB
;CALL MOVEI F,DDB
; PUSHJ P,NETWAK
;RETURN CPOPJ ;JOB(PC) WILL BE @ NETHIB
NETWAK::PUSHJ P,SAVJW ;SAVE J AND W
LDB T1,PJOBN## ;GET THE JOB NUMBER
PJRST EWAKE## ;WAKE THE JOB
;SUBROUTINE NETSLP - PUT THE JOB TO SLEEP FOR 2 SECONDS
;CALL MOVEI F,DDB
; PUSHJ P,NETSLP
;RETURN CPOPJ ;AFTER 2 SECOND
NETSLP::PUSHJ P,SAVJW ;SAVE J AND W
PUSHJ P,SAVT## ;SAVE THE T'S DON'T KNOW WHO IS CALLING
PUSHJ P,SVEVM ;SAVE ANY EVM THE JOB MAY HAVE
LDB J,PJOBN## ;GET THE JOB NUMBER
MOVEI T1,2 ;TWO SECONDS
PUSH P,F ;SLEEP ZEROES F
PUSHJ P,SLEEP## ;SLEEP
JFCL ;MAYBE
PJRST FPOPJ## ;RETURN
SUBTTL INPDIS - DISMISS THE INPUT INTERRUPT
;SUBROUTINE INCTBD - RECORD AND DISCARD A BAD INPUT MESSAGE
;CALL MOVEI U,PCB
; MOVEI J,FEK
; MOVEI T1,.
; PUSHJ P,INCTBD ;USUALLY PJSP T1,INCTBD
;RETURN CPOPJ
INCTBD: AOS %NTBAD ;COUNT THIS MESSAGE
HRRZ W,PCBNDB(U) ;ENSURE W IS SETUP (MAY BE 0)
HRLI U,(T1) ;KEEP PC OF FINDER IN LH OF %NTBLC
EXCH U,%NTBLC ;SAVE, GET LAST ONE
HRRZM U,FEKIAD(J) ;USE THAT (OR 0) FOR NEXT MSG (SEE NETRDX)
PJRST INPDI1 ;DISMISS INTERRUPT
;SUBROUTINE INPDIS - DISMISS THE INTERRUPT
;CALL MOVEI U.PCB
; MOVEI J,FEK
; PUSHJ P,INPDIS
;RETURN CPOPJ ;USUALLY TO THE FEK FOR A DISMISS
INPDIS: HRRZ W,PCBNDB(U) ;ENSURE W SETUP
INPDI1: SOSGE FEKBSI##(J) ;REDUCE THE INPUT READ REQUEST
PJRST NETRDX ;READ ANOTHER BUFFER
STOPCD INPDI2,DEBUG,BFU,;++BUSY FOULED UP
INPDI2: SETOM FEKBSI##(J) ;SET IT IDLE
POPJ P, ;RETURN
;SUBROUTINE NETHRU - SEND A ROUTE THROU MESSAGE
;CALL MOVEI U,PCB
; JRST NETHRU
;RETURN (NEVER) ;GO TO INPDIS
NETHRU: ;ENTRY
PUSH P,J ;SAVE THE INPUT FEK
PUSHJ P,SRCNDB ;FIND THE NODE TO SEND THE MESSAGE
JSP T1,[POP P,J ;RESTORE THE INPUT FEK
JRST INCTBD] ;ILLEGAL MESSAGE
HRRZ J,NDBFEK##(W) ;GET THE OUTPUT FEK
CONO PI,PIOFF ;TURN OFF THE PI SYSTEM(FRCWRT TURNS ON)
PUSHJ P,FRCWRT ;SEND THE MESSAGE
POP P,J ;RESTORE THE INPUT FEK
SETZB W,FEKIAD##(J) ;CLEAR THE PCB AND INPUT POINTER
JRST INPDIS ;DISMISS THE INTERRUPT
;SUBROUTINE NETRDD - SET UP A READ REQUEST TO THE FRONT END
;CALL MOVEI J,FEK ;FEK TO READ
; PUSHJ P,NETRDD
;RETURN CPOPJ
NETRDD: SETZ W, ;CLEAR THE NODE POINTER
NETRDX: CONO PI,PIOFF## ;TURN THE PI OFF
SKIPL FEKBSI##(J) ;IS THERE A READ REQUEST
PJRST ONPOPJ## ;YES, EXIT
AOS FEKBSI##(J) ;SET BUSY
CONO PI,PION## ;TURN PI ON
SETZ F, ;CLEAR THE DDB POINTER
HRRZ U,FEKIAD##(J) ;THE THE PCB POINTER
JUMPN U,NETRD1 ;JUMP IF ALLOCATED
PUSHJ P,MAKPCB ;MAKE A PCB
JRST INPDI2 ;CLEAR BUSY AND EXIT
SETZM PCBNDB##(U) ;CLEAR THE NDB POINTER
MOVEI T2,^D128 ;BUFFER SIZE
PUSHJ P,GETZWD ;GET THE BUFFER SPACE
JRST [SETOM FEKBSI##(J) ;CLEAR BUSY
PJRST RMVPCB] ;NONE AVAILABLE REMOVE THE PCB
JRST NETRD2 ;CONTINUE
NETRD1: HRRZ T1,PCBIAD##(U) ;GET THE BUFFER POINTER
NETRD2: HRLI T1,(POINT 8) ;EIGHT BIT BYTE POINTER
MOVEM T1,PCBIAD##(U) ;STORE IN THE PCB
MOVE T1,[XWD ^D128,^D512] ;GET THE COUNT FIELD
MOVEM T1,PCBICT##(U) ;STORE THE COUNT FIELD
HRRZM U,FEKIAD##(J) ;STORE THE PCB POINTER
PUSH P,W ;SAVE THE NDB POINTER
XCT FEKRDD##(J) ;CALL THE FRONT END KONTROLLER
POP P,W ;RESTORE NDB
JUMPE W,CPOPJ## ;EXIT IF NO NDB (ROUTE THRU)
MOVSI T1,.RMSUI## ;GET THE IDLE BIT
TDNE T1,SCBSTS##(W) ;IS IT IDLE
PJRST SCNTTO ;NO, SCAN THE TTY'S
POPJ P, ;YES, EXIT
SUBTTL INPINT - INPUT INTERRUPT PROCESSOR FOR ALL FEK'S
;SUBROUTINE INPINT - INPUT INTERRUPT
;CALL MOVE J,[XWD FLAGS,FEK]
; PUSHJ P,INPINT
;RETURN CPOPJ
INPINT: PUSHJ P,SAVE4## ;SAVE THE P'
MOVEI P4,300 ;DUMMY COUNT FOR HEADER PORTION OF A MESSAGE
SETZB W,F ;CLEAR THE NDB POINTER,DDB POINTER
HRRZ U,FEKIAD##(J) ;GET THE INPUT PCB POINTES
MOVE P1,PCBIAD##(U) ;GET THE IOPUT MESSAGE POINTER
HRRE T1,PCBICT##(U) ;GET THE INPUT BYTE COUNT
JUMPLE T1,INPIN0 ;ZERO LENGTH IS ILLEGAL
IDIVI T1,4 ;CONVERT TO WORDS AND BYTES
ADDI T1,(P1) ;RELOCATE TO THE BUFFER
ADD T1,[POINT 8,0,7 ;BUILD A DEPOSITE TABLE
POINT 8,0,15
POINT 8,0,23
POINT 8,0,31](T2)
DPB W,T1 ;SET A TERMINATING 0 BYTE
;NCT
PUSHJ P,EBI2BI ;READ THE FLAGS
HRLI U,(T1) ;COPY THE FLAGS
ANDI T1,NCT.TP ;JUST THE MESSAGE TYPE
IFN FTCMSR,<
AOS NCLRTP(T1) ;TALLY
>
TLNE U,NCT.RH ;ROUTINE HEADER PRESENT
JRST INPIN1 ;YES,
CAIE T1,NCT.ID ;IS THIS AN ID MESSAGE
INPIN0: PJSP T1,INCTBD ;NO, BAD MESSAGE (N.B. HERE FROM ABOVE TO SETUP T1)
JRST INCTID ;YES, PROCESS NODE ID MESSAGE
INPIN1:
;DNA
PUSHJ P,EBI2BI ;GET <DNA>
SKIPN T1 ;IS IT NULL
MOVEI T1,OURNNM## ;USER OURS
CAIE T1,OURNNM## ;FOR THIS NODE
JRST NETHRU ;RE-ROUTE THE MESSAGE OUT THE OTHER END
;SNA
PUSHJ P,EBI2BI ;YES, GET THE <SNA>
PUSHJ P,SRCNDB ;FIND THE NODE BLOCK
PJSP T1,INCTBD ;SOURCE WENT AWAY
HRRZM W,PCBNDB##(U) ;SAVE THE NDB POINTER
;NCA
ILDB T1,P1 ;GET THE ACK NUMBER
MOVE T2,NDBFEK##(W) ;GET STATUS BITS
TLNN T2,NDB.SK## ;SKIP IF EXCHANGED START/STAK
JRST [TLNN U,NCT.TP ;NUMBERED MESSAGE?
PJSP T1,INCTBD ;YES, JUST THROW IT AWAY
IBP P1 ;NO, FIX UP BYTE POINTER
JRST INCTUN] ;PROCESS IT
PUSHJ P,CHKNCA ;ACK ALL MESSAGE POSSIBLE
;NCN
ILDB T1,P1 ;GET THIS MESSAGE NUMBER
TLNE U,NCT.TP ;NUMBERED MESSAGE
JRST INCTUN ;NO, UNNUMBERED
DPB T1,NDBLMR## ;STORE LAST MESAGE RECEIVED
LDB T2,NDBLMP## ;GET LAST MESSAGE PROCESSED
ADDI T2,1 ;GET NEXT SEQUENTIAL MESSAGE NUMBER
ANDI T2,377 ;ONLY 8 BITS
;***** CAIN T1,(T2) ;IS THIS MESSAGE IN SEQUENCE
JRST INCTNM ;YES, SEQUENTIAL MESSAGE
;HERE IF A MESSAGE ARRVICES OUT OF ORDER
SUBTTL CHKNCA - CHECK ACK'S FOR MESSAGE SENT BUT BEING HELD
;SUBROUTINE CHKNCA - DELETE MESSAGE THE HAVE ACK'S
;CALL MOVEI W,NDB
; MOVEI T1,NCA - MESSAGE ACK NUMBER
;RETURN CPOPJ
CHKNCA: ;ENTRY
JUMPE W,CPOPJ## ;EXIT IN NDB UNDEFINED
PUSHJ P,SAVE1## ;SAVE P1
MOVEI P1,(T1) ;COPY THE ACK
PUSH P,U ;SAVE THE OLD PCB
DPB T1,NDBLAR## ;SAVE THE LAST ACK RECEIVED
CHKNC1: LDB T2,NDBLAP## ;LST ACK PROCESSED
CHKNC2: CAIN T2,(P1) ;PROCESSED ALL ?
JRST UPOPJ## ;ALL DONE
MOVEI T1,(P1) ;GET ACK NUMBER
SUBI T1,(T2) ;MINUS THE LAST ACK PROCESSED
ANDI T1,377 ;MAKE 8 BITS ONLY
LDB T3,NDBLMS## ;GET LAST MESSAGE SENT
SUBI T3,(T2) ;MINUS LAST ACK PROCESSED
ANDI T3,377 ;8 BITS
CAIGE T3,(T1) ;IS THIS ACK IN RANGE
JRST UPOPJ## ;NO IGNORE THE ACK
ADDI T2,1 ;UPDATE ACK COUNT
ANDI T2,377 ;ONLY 8 BITS
DPB T2,NDBLAP## ;REMEMBER
HRRZ U,NDBQUE##(W) ;GET THE QUEUE POINTER
JUMPE U,CHKNC2 ;NO ENTRIES
LDB T3,PCBMSN## ;GET THIS MESSAGES NUMBER
CAIE T3,(T2) ;IS THIS THE ONE
JRST CHKNC2 ;NO, CHECK THE NEXT
MOVE T3,PCBBLK##(U) ;GET THE QUEUE LINK
HRRM T3,NDBQUE##(W) ;STEP TO THE NXT MESSAGE
PUSHJ P,RMVPCB ;REMOVE THE PCB
JRST CHKNC1 ;TRY THE NEXT PCB
SUBTTL - PROCESS THE TOPS MESSAGE ON THE QUEUE IN SEQUENCE
INCTNM: ;HERE FOR NEXT MESSAGE
JUMPN W,.+2 ;IF THERE'S A SOURCE PROCESS MESSAGE
PJSP T1,INCTBD ;ELSE COMPLAIN ABOUT BAD MESSAGE
DPB T1,NDBLMP## ;SAVE LAST MESAGE PROCESSED
JRST INCTDM ;PROCESS NUMBERED DATA MESSAGE
INCTUN: HLRZ T1,U ;GET THE FLAGS
ANDI T1,NCT.TP ;GET THE TYPE FIELD
JRST @NCTTBL(T1) ;DISPATCH BY THE MESSAGE TYPE
NCTTBL: JRST INCTDM ;(0) DATA MESSAGE
JRST INCTAK ;(1) ACK
JRST INCTNK ;(2) NAK
JRST INCTRP ;(3) REP
JRST INCTST ;(4) START
JRST INCTSK ;(5) STACK
JRST INCTID ;(6) NODE ID
JRST INPDIS ;(7) ILLEGAL INPUT MESSAGE TYPE
SUBTTL INCTID - NODE ID MESSAGE PROCESSOR
INCTID: ;ENTRY
;NCA
ILDB T1,P1 ;GET THE ACK START
;NCN
ILDB T1,P1 ;GET THE STARTING MESSAGE NUMBER
;NNM
PUSHJ P,EBI2BI ;READ THE NODE NUMBER
PUSHJ P,SRCNDB ;DOES THE NODE EXIST
CAIA ;NO
JRST INCTI0 ;YES, MUST BE A RESTART
PUSHJ P,MAKNDB ;MAKE A NODE DATA BLOCK
JRST INPDIS ;NO CORE DO IT NEXT TIME
;OPD
INCTI0: PUSHJ P,RDOPDD ;READ THE OPTIONAL DATA
PJRST INPDIS ;DISMISS
PUSH P,W ;SAVE THE NDB POINTER
HLRZ T1,NDBNNM##(W) ;GET THE NODE NUMBER
MOVEI W,NETNDB## ;GET OUR NODE BLOCK
PUSHJ P,SRCTOP ;DO WE KNOW HIM
CAIA ;NO
JRST INCTI1 ;YES, DO NOT MAKE AN ENTRY
PUSH P,T1 ;SAVE THE NODE NUMBER
SETZ T1, ;SEARCH FOR AN OPEN SLOT
PUSHJ P,SRCTOP ;IN THE TOPOLOGY TABLE
JRST INCTI1 ;NONE AVAILABLE
POP P,T1 ;RESTORE THE NODE NUMBER
LSH T1,^D8 ;POSITION
IORI T1,1 ;ADD THE LINK VALUE
DPB T1,T4 ;STORE THE NEIGHBOR
PUSHJ P,SETNBN ;SET UP TO SEND NEIGHBORS
INCTI1: POP P,W ;RESTORE THE NDB POINTER
JRST INPDIS ;DISMISS
;INCTST - START MESSAGE PROCESSOR
INCTST: ;ENTRY
;NNM
PUSHJ P,EBI2BI ;READ THE NODE NUMBER
PUSHJ P,SRCNDB ;DOES THE NDOE EXIST
JRST INPDIS ;NO, WAIT FOR A NEIGHBORS MESSAGE
HRLZI T1,NDBCLR##(W) ;GET FIRST WORD TO CLEAR
HRRI T1,NDBCLR##+1(W);SECOND WORD
SETZM NDBCLR##(W) ;CLEAR THE FIRST WORD
BLT T1,NDBLEN##-1(W) ;CLEAR THE REST OF THE BLOCK
MOVSI T1,NDB.CF##
ANDCAM T1,NDBFEK##(W) ;CLEAR REQUEST CONFIG FLAG
PUSHJ P,RDOPDD ;READ THE OPTIONAL DATA
PJRST INPDIS ;DISMISS
MOVSI T1,NDB.ST## ;GET THE START BIT
IORM T1,NDBFEK##(W) ;STORE
PUSH P,U ;SAVE THE PCB POINTER
PUSHJ P,NCSSTK ;SEND A STACK BACK
JFCL ;TRY LATER
POP P,U ;RESTORE THE PCB
JRST INCTS1 ;COMMON EXIT TO CLEAR NUMBERS
;SUBROUTINE INCTSK - STACK MESSAGE PROCESSOR
INCTSK: ;ENTRY
;NNM
PUSHJ P,EBI2BI ;READ THE NODE NUMBER
PUSHJ P,SRCNDB ;FIND THE NDB
JRST INPDIS ;WAIT FOR A NODE DATA BLOCK
PUSHJ P,RDOPDD ;READ THE OPTIONAL DATA
PJRST INPDIS ;DISMISS THE INTERRUPT
MOVSI T1,NDB.SK## ;GET START FLAG
IORM T1,NDBFEK##(W) ;SET THE FLAG
INCTS1: JRST INPDIS ;DISMISS THE INTERRUPT
;SUBROUTINE INCTAK - ACK MESSAGE PROCESSOR
INCTAK: ;ENTRY
;ACK'S HAPPEN IN THE HEADER ROUTINE
JRST INPDIS ;DISMISS THE INTERRUPT
;SUBROUTINE INCTNK NAK MESSAGE PROCESSOR
INCTNK: ;ENTRY
JUMPE W,INPDIS ;JUNK IN THE PIPE
PUSH P,P1 ;SAVE P1
PUSH P,U ;SAVE THE PCB
HRRZ P1,NDBQUE##(W) ;GET THE POINTER
HLLZS NDBQUE##(W) ;NO LONGER WAITING FOR ACK
JUMPE P1,INCTN2 ;EMPTY
INCTN1: MOVEI U,(P1) ;GET THE NEXT ENTRY
HRRZ P1,PCBBLK##(U) ;GET THE NEXT ENTRY
PUSHJ P,NETWRT ;RESEND THE MESSAGE
JUMPN P1,INCTN1 ;CHECK FOR THE END
INCTN2: POP P,U ;RESTOE THE PCB
POP P,P1 ;RESTORE P1
JRST INPDIS ;DISMISS THE INTERRUPT
;SUBROUTINE INCTRP REP PROCESSOR
INCTRP: ;ENTRY
JUMPE W,INPDIS ;JUNK IN THE PIPE
PUSH P,P1 ;SAVE P1
PUSH P,U ;SAVE THE PCB
HLRZ P1,NDBQUE##(W) ;GET THE INPUT QUEUE POINTER
JUMPE P1,INCTR2 ;NONE MUST SEND AN ACK
INCTR1: MOVEI U,(P1) ;COPY THE PCB POINTER
HRRZ P1,PCBBLK##(U) ;STEP TO THE NEXT ENTRY
PUSHJ P,RMVPCB ;REMOVE THIS PCB
JUMPN P1,INCTR1 ;CONTINUE
LDB T1,NDBLMP## ;GET LAST MESSAGE PROCESSED
DPB T1,NDBLMR## ;STORE AS LAST MESSAGE RECEIVED
PUSHJ P,NCSNAK ;SEND A NAK
JFCL ;DON'T CARE
JRST INCTR3 ;CONTINUE TO EXIT
INCTR2: PUSHJ P,NCSAKK ;SEND A ACK
JFCL ;DON'T CARE
INCTR3: POP P,U ;RESTORE U
POP P,P1 ;RESTORE P1
JRST INPDIS ;DISMISS THE INTERRUPT
;SUBROUTINE RDOPDD - INSERT THE SOFTWARE ID <NNM><SNM><SID>
;CALL MOVEI U,PCB
; MOVEI W,NDB OR 0
; PUSHJ P,RDOPDD
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;W=NDB
RDOPDD: ;ENTRY
SETZB T1,NDBMNM##(W) ;CLEAR THE MESSAGE NUMBER
DPB T1,NDBLAS## ;AND THE ACK COUNTERS
HLLZS NDBSNM##(W) ;..
;SNM
HLRZ P2,NDBSNM##(W) ;CHECK FOR A POINTER
JUMPN P2,RDOPD1 ;YES
MOVEI T2,1 ;STATION NAME POINTER(SIXBIT)
PUSHJ P,GETZWD ;ALLOCATE SPACE
POPJ P, ;NO, SPACE
HRLM T1,NDBSNM##(W) ;STORE THE POINTER
MOVEI P2,(T1) ;OUTPUT POINTER FOR COPY
RDOPD1: PUSHJ P,EAS2SX ;COPY THE STATION NAME
MOVEM T1,(P2) ;STORE THE STATION NAME
;SID
HRRZ P2,NDBSID##(W) ;CHECK FOR A POINTER
JUMPN P2,RDOPD2 ;YES
MOVEI T2,^D8 ;ALLOCATE SPACE FOR THE SYSTEM NAME
PUSHJ P,GETZWD ;FROM FREE CORE
POPJ P, ;NO CORE
HRRM T1,NDBSID##(W) ;STORE THE POINTER
MOVEI P2,(T1) ;GET THE POINTER
RDOPD2: PUSHJ P,EAS2AS ;COPY THE SYSTEM NAME
HLRZ P2,NDBSID##(W) ;GET THE POINTER
JUMPN P2,RDOPD3 ;JUMP IF ONE
MOVEI T2,^D8 ;ALLOCATE SPACE FOR THE CREATION DATE
PUSHJ P,GETZWD ;FROM FREE CORE
POPJ P, ;NO SPACE
HRLM T1,NDBSID##(W) ;STORE THE POINTER
MOVEI P2,(T1) ;COPY THE POINTER
RDOPD3: PUSHJ P,EAS2AS ;COPY THE CREADTION DATE
PUSHJ P,ONLNDB ;TYPE ONLINE MESSAGE
IFN FTPI,<
PUSHJ P,PSINTC ;SIGNAL NETWORK TOPOLOGY CHANGE
>
PJRST CPOPJ1## ;EXIT
SUBTTL INCTDM - PROCESS OF NUMBERED CONTROL/DATA MESSAGES
INCTDM: ;ENTRY
;DLA
PUSHJ P,EBI2BI ;GET THE DESTINATION LINK ADDRESS
JUMPN T1,IDCCTL ;DEVICE CONTROL MESSAGE
;
;HERE TO PROCESS NUMBERD CONTROL MESSAGES
;
;CNT
NCTDSP: MOVEI P4,2 ;ALLOW 2 BYTES OF COUNT
PUSHJ P,EBI2BI ;GET THE MESSAGE COUNT FIELD
MOVEI P4,(T1) ;COPY THE COUNT FIELD
JUMPE P4,INPDIS ;END OF MESSAGE
;CM
PUSHJ P,EBI2BI ;GET THE MESSAGE TYPE
CAILE T1,NC.MAX ;IN RANGE?
PJSP T1,INCTBD ;NO, DISCARD
IFN FTCMSR,<
AOS NCLRMT(T1) ;RECORD THIS ONE
>
PUSHJ P,ICMTBL(T1) ;DISPATCH TO THE CONTROL PROCESSORS
PJSP T1,INCTBD ;ILLEGAL MESSAGE
NCTDS1: JUMPLE P4,NCTDSP ;TRY ANOTHER MESSAGE
PUSHJ P,EAS2SX ;REMOVE THE EXTRA PART OF THE MESSAGE
JRST NCTDS1 ;TRY AGAIN
ICMTBL:
JRST CPOPJ## ;<0> IS ILLEGAL
JRST ICMCNT ;<1> CONNECT
JRST ICMDSC ;<2> DISCONNECT
JRST ICMNBN ;<3> NEIGHBOURS
JRST ICMRCF ;<4> REQUEST CONFIGURATION
JRST ICMCNF ;<5> CONFIGURATION
JRST ICMDRQ ;<6> DATA REQUEST
JRST ICMCTL ;<7> STATION CONTROL
SUBTTL ICMXXX MESSAGE PROCESSORS
;SUBROUTINE ICMCNT - CONNECT
ICMCNT: ;ENTRY
;DLA
PUSHJ P,EBI2BI ;GET THE DESTINATION LINK ADDRESS
JUMPE T1,ICMCNN ;THIS IS A CONFIRM COMMECT CALL
CAIGE T1,LATLEN## ;YES, CHECK RANGE
SKIPN F,NETLAT##(T1) ;GET THE DDB ADDRESS
POPJ P, ;BAD MESSAGE
JUMPL F,TTYCNX ;ITS A LDB IE TTY CONNECT CONFIRM
;SLA
PUSHJ P,EBI2BI ;GET THE SOURCE NODE ADDRESS
JUMPE T1,CPOPJ## ;ILLEGAL MESSAGE IF SOURCE IS ZERO
DPB T1,NETDLA## ;SAVE THE SOURCE
;DPN
;OBJ
PUSHJ P,EBI2BI ;GET THE OBJECT TYPE
;PID
PUSHJ P,EBI2BI ;GET THE UNIT NUMBER
;SPN
;OBJ
PUSHJ P,EBI2BI ;GET THE SOURCE OBJECT TYPE
IFN FTTSK,<
CAIN T1,OBJ.TK ;TASK CONFIRM
JRST ICMCN1 ;YES, IGNORE THE REST OF THE MESSAGE
>
;PID
PUSHJ P,EBI2BI ;UNIT NUMBER
ANDI T1,7 ;ONLY THREE BITS WORTH
DPB T1,PUNIT## ;STORE AS THE REAL UNIT NUMBER
ADDI T1,'0' ;TO SIXBIT
DPB T1,[POINT 6,DEVNAM(F),35] ;STORE THE UNIT NUMBER
;MML
PUSHJ P,EBI2BI ;GET THE MAX RECORD LENGTH
;FEA
;DCM
PUSHJ P,EBI2BI ;GET THE MODE FIELD
;RLN
PUSHJ P,EBI2BI ;GET THE RECORD LENGTH
DPB T1,NETRLN## ;STORE RECORD LENGTH
;DVT
PUSHJ P,EBI2BI ;GET THE DEVICE ATTRIBUTES
DPB T1,NETDVT## ;STORE IN THE DDB
ICMCN1: MOVSI S,IOSCON ;DEVICE NOW CONNECTED
IORM S,DEVIOS(F) ; AND READY FOR USE
SETZ T1, ;SET THE REASON TO ZERO FOR SUCCESS
DPB T1,NETRSN## ;SET THE REASON BYTE
PUSHJ P,NETWAK ;WAKE THE JOB
PJRST CPOPJ1## ;EXIT
SUBTTL ICMCNN - ANOTHER NODE IS ATTEMPTING TO CONNECT TO OUT DEVICE OR TASK
ICMCNN: ;ENTRY FROM ABOVE
PUSH P,U ;SAVE THE PCB
;SNA
PUSHJ P,EBI2BI ;GET THE SNA
PUSH P,T1 ;SAVE THE SNA
;DPN
;OBJ
PUSHJ P,EBI2BI ;GET THE OBJECT TYPE
MOVE T2,(P) ;GET THE LINK ADDRESS
SETZ T3,
CAIN T1,OBJ.TT ;TTY CONNECT TO MCR?
MOVEI T3,TTYCNZ ;YES
IFN FTTSK,<
CAIN T1,OBJ.TK ;TASK?
MOVEI T3,TSKCNT## ;YES
>
JUMPE T3,ICMCN2 ;DISCONNECT IF NOT A RECOGNIZED DEVICE
PUSHJ P,(T3) ;TRY TO CONNECT
JRST ICMCN3 ;CAN'T, SEND DISCONNECT
POP P,T1
JRST UPOPJ1## ;CONNECTION COMPLETE
ICMCN2: MOVEI T2,RSN.OT ;OBJECT TYPE NOT AVAILABLE
ICMCN3: POP P,T1 ;RESTORE LINK ADDRESS
MOVEI F,0 ;ENSURE NCSDSC WON'T WAIT FOR RESPONSE
PUSHJ P,NCSDSC ;SEND A DISCONNECT
JFCL ;IGNORE ERROR (PICKED UP LATER)
JRST UPOPJ1## ;DISMISS THE MESSAGE
SUBTTL ICMDSC - DISCONNECT
ICMDSC: ;ENTRY
;DLA
PUSHJ P,EBI2BI ;GET THE DESTINATION LINK ADDRSS
JUMPE T1,CPOPJ## ;ILLEGAL MUST HAVE A DESTINATION
CAIGE T1,LATLEN## ;CHECK RANGE
SKIPN F,NETLAT##(T1) ;GET THE DDB
POPJ P, ;MUST HAVE A DDB
JUMPL F,DSCTTY ;DISCONNECT A TTY
MOVSI T1,NT.DSC## ;LET NCSDSC FIGURE OUT THAT
IORM T1,NETSTS##(F) ;DISCONNECT SEQUENCE IS COMPLETE
MOVE S,DEVIOS(F)
TLZN S,IOSCON ;SAY WE'RE NO LONGER CONNECTED
JRST ICMDS1 ;NO NEED TO CALL TSKDSC IF A CONFIRM
IFN FTTSK,<
LDB T1,DEYTYP## ;GET THE DEVICE TYPE
CAIN T1,<.TYTSK/.TYEST>;IS IT A TSK
PUSHJ P,TSKDSC## ;YES, SPECIAL DISCONNECT FOR A TSK
>;END FTTSK
;SLA
ICMDS1: PUSHJ P,EBI2BI ;GET THE SOURCE (IGNORE)
;RSN
PUSHJ P,EBI2BI ;GET THE REASON FOR THE DISCONNECT
DPB T1,NETRSN## ;STORE STATUS
PUSHJ P,NETWAK ;YES, WAKE THE JOB
AOS (P) ;FOR SUCCESSFUL RETURN
PJRST STOIOS## ;REMEMBER NEW S
;SUBROUTINE ICMNBN - NEIGHBOURS
ICMNBN: ;ENTRY
PUSH P,U ;SAVE THE PCB
HRLI T1,NDBTOP##(W) ;MUST CLEAR THE OLD TABLE FIRST
HRRI T1,NDBTOP##+1(W) ;...
SETZM NDBTOP##(W)
BLT T1,NDBTOP##+7(W)
MOVE T4,[POINT 18,NDBTOP##(W)] ;POINTER TO THE TOP TABLE
MOVEI T3,^D16 ;MAX SISTEEN NEIGHBORS PER NODE
ICMNB1: JUMPLE P4,ICMNB2 ;END OF MESSAGE EXIT
PUSHJ P,EBI2BI ;GET A NODE NUMBER
LSH T1,^D8 ;POSITION
ILDB T2,P1 ;GET THE LINK VALUE
SUBI P4,1 ;COUNT THE CHARACTER
ANDI T2,377 ;ONLY EIGHT BITS WORTH
IORI T1,(T2) ;COMBINE
IDPB T1,T4 ;STORE IN THE TABLE
SOJG T3,ICMNB1 ;CONTINUE
;HERE TO RECOMPUT THE TOPOLOGY OF THE NETWORK BASED ON A NEIGHBORS CHANG
ICMNB2: PUSH P,W ;SAVE THE NDB POINTER
MOVEI W,NETNDB## ;START THE SEARCH WITH OUR NEIGHBORS
PUSHJ P,SRCNBN ;START THE SEARCH
;HERE TO SEARCH FOR LOST NODES IN THE NETWORK
ICMNB3: MOVEI W,NETNDB## ;GET THE START OF THE LIST
ICMNB4: HRRZ W,NDBNNM##(W) ;GET THE NEXT NODE DATA BLOCK
JUMPE W,ICMNB5 ;END OF BLOCKS
MOVSI T1,NDB.TP## ;GET THE TOPOLOGY SEARCH FLAG
TDNE T1,NDBFEK##(W) ;WAS THIS NODE SEEN
JRST ICMNB4 ;YES, CONTINUE
PUSHJ P,RMVNDB ;NO LOST NODE REMOVE IT
JRST ICMNB3 ;CONTINUE
;HERE TO REMOVE ALL THE NDB.TP FLAGS
ICMNB5: MOVEI W,NETNDB## ;START AT THE FIRST OF THE LIST
MOVSI T1,NDB.TP## ;GET THE TOPOLOGY SEARCH FLAG
ICMNB6: HRRZ W,NDBNNM##(W) ;GET THE NEXT NDB
JUMPE W,ICMNB7 ;END OF THE LIST
ANDCAM T1,NDBFEK##(W) ;CLEAR IT
JRST ICMNB6 ;CONTINUE
ICMNB7: POP P,W ;RESTORE THE NDB POINTER
JRST UPOPJ1## ;DISMISS THE MNESSAGE
SRCNBN: PUSH P,[POINT 18,NDBTOP##(W)] ;POINTER TO THE TOPOLOGY TABLE
SRCNB1: ILDB T1,(P) ;GET THE NEXT ENTRY
LSH T1,-^D8 ;POSITION THE NNM
HRRZ T2,(P) ;GET THE POSITION IN THE TABLE
CAILE T2,NDBTOP##+^D7 ;STILL IN RANGE
JRST TPOPJ## ;NO END OF TABLE
JUMPE T1,SRCNB1 ;ZERO ENTRY GET THE NEXT ENTRY
PUSH P,W ;AVE THE NDB POINTER
PUSHJ P,SRCNDB ;IS THIS ENTRY DEFINED
CAIA ;IS THIS A KNOWN NODE
JRST SRCNB2 ;YES,
PUSHJ P,MAKNDB ;MAKE A NODE DATA BLOCK FOR THIS NODE
JRST [POP P,W ;RESTORE THE NDB POINTER
JRST SRCNB1] ;CONTINUE
SRCNB2: MOVSI T2,NDB.TP## ;GET THE TOPOLOGY SEARCH BIT
TDNE T2,NDBFEK##(W) ;WAS THIS NODE SEEN BEFORE
JRST [POP P,W ;YES, THIS IS A MULTI PATCH
JRST SRCNB1] ;CONTINUE SEARCH
IORM T2,NDBFEK##(W) ;NO, BUT NOW WE SEE IT DON'T WE
PUSHJ P,SRCNBN ;SEARCH HIS TABLES
POP P,W ;RESTORE OUT NDB
JRST SRCNB1 ;CONTINUE THE SEARCH
;SUBROUTINE SRCTOP - SEARCH A TOPOLOGY TABLE AND RETURN THE ENTRY
;CALL MOVEI W,NDB
; MOVEI T1,NNM ;TO SEARCH FOR
;RETURN CPOPJ ;NOT FOUND
; CPOPJ1 ;FOUND T4=BYTE POINTER
SRCTOP: ;ENTRY
PUSH P,T1 ;SAVE THE ARGUMENT
LSH T1,^D8 ;POSITION FOR COMPARE
MOVE T4,[POINT 18,NDBTOP##(W)] ;START OF TABLE
MOVSI T3,-<^D16> ;MAX ENTRIES
SRCTO1: ILDB T2,T4 ;GET THE NEXT ENTRY
ANDI T2,377400 ;ONLY THE NODE NUMBER
CAIN T1,(T2) ;IS THIS THE ENTRY
JRST TPOPJ1## ;YES, EXIT
AOBJN T3,SRCTO1 ;TRY AGAIN
PJRST TPOPJ## ;NO SUCH ENTRY
;SUBROUTINE ICMRCF - REQUEST CONFIGURATION
ICMRCF: ;ENTRY
PUSH P,U ;SAVE THE PCB
PUSHJ P,NCSCNF ;SEND THE CONFIGURATION MESSAGE
JFCL ;LATER
PJRST UPOPJ1## ;EXIT
;SUBROUTINE ICMCNF - CONFIGURATION
ICMCNF: ;ENTRY
MOVSI T1,NDB.CF## ;GET THE CONFIGURATION BIT
IORM T1,NDBFEK##(W) ;SEEN THE CONFIGURATION MESSAGE
JUMPE P4,CPOPJ1## ;NO DEVICES
ZZ==0
REPEAT <OBJ.MX/4>+1,<
SETZM SCBDEV##+ZZ(W) ;CLEAR THE DEVICE TABLE(S)
ZZ==ZZ+1
>;END OF REPEAT
PUSH P,P2 ;SAVE P2
ICMCF1:
;OBJ
PUSHJ P,EBI2BI ;GET THE OBJECT TYPE
CAILE T1,OBJ.MX ;CHECK THE RANGE
JRST [POP P,P2 ;RESTORE P2
POPJ P,] ;DISMISS THE MESSAGE
MOVEI P2,(T1) ;COPY THE DEVICE NUMBER
;NDEV
PUSHJ P,EBI2BI ;GET THE COUNT
CAILE T1,200 ;ALLOW ONLY 128 FOR NOW
MOVEI T1,200
DPB T1,NETCNF##(P2) ;STORE NEW COUNT
CAIN P2,OBJ.TY ;IS IT A TTY?
MOVEM T1,SCBTTY##(W) ;STORE TTY COUNT
;PID
ICMCF3: PUSHJ P,EAS2SX ;GET THE PID
JUMPG P4,ICMCF1 ;CONTINUE THROUGH THE MESSAGE
POP P,P2 ;RESTORE P2
MOVEI T1,ST.NRT
TDNE T1,STATES##
JRST CPOPJ1##
PUSHJ P,TTYCNT ;START CONNECTING TTY'S
JRST CPOPJ1
JRST CPOPJ1 ;ALWAYS GIVE GOOD RETURN
;SUBROUTINE ICMDRQ - DATA REQUEST
ICMDRQ: ;ENTRY
;DLA
PUSHJ P,EBI2BI ;GET THE DESTINATION LINK
JUMPE T1,CPOPJ## ;ILLEGAL IF 0
CAIGE T1,LATLEN## ;CHECK THE RANGE
SKIPN F,NETLAT##(T1) ;GET THE DDB
POPJ P, ;OUT OF RANGE
;DRQ
PUSHJ P,EBI2BI ;GET THE REQUEST COUNT
JUMPL F,TTYDRQ ;YES, GO TO TTY ROUTINE
ANDI T1,777 ;ONLY ALLOW A REQUEST THAT IS REASONABLE
ADDM T1,NETDRQ##(F) ;UPDATE THE OUTPUT DATA REQUEST COUNT
AOS (P) ;SKIP RETURN
MOVEI T1,DEPAIO ;NON, BLOCKING I/O
TDNN T1,DEVAIO(F) ;FOR THIS DEVICE
PJRST NETWAK ;NO, WAKE UP THE JOB
PUSH P,DEVIOS(F) ;SAVE THE REAL DEVIOS
MOVSI S,IO ;GET THE DIRECTION BIT
IORB S,DEVIOS(F) ;SET DIRECTION AS OUTPUT
TLZ S,IOSTBL ;CLEAR TROUBLE SO SETIOD WILL CALL PSIIOD
PUSHJ P,SETIOD## ;SET IO DONE
POP P,DEVIOS(F) ;RESTORE THE REAL DEVIOS
POPJ P, ;RETURN
;SUBROUTINE ICMCTL - STATION CONTOL
ICMCTL: ;ENTRY
PUSHJ P,SAVJW ;SAVE J AND W
JUMPLE P4,ICMCT5 ;END OF MESSAGE
PUSH P,P1 ;SAVE THE POSITION
IBP P1 ;SKIP THE LINE NUMBER
ILDB T1,P1 ;GET THE FUNCTION
POP P,P1 ;NO, RESTORE THE BYTE POINTER
SKIPE T4,SCBCTL##(W) ;IS THE STATION CONTROL DEVICE ASSIGNED
JRST ICMCT0 ;YES, PROCESS THE MESSAGE
CAIE T1,15 ;IS THIS A REQUEST TO BOOT A STATION
CAIN T1,14 ;IS THIS A REQUEST TO LOAD A STATION
JRST RQBOOT ;YES, GO LOAD THE BOOT STRAP ROUTINE
POPJ P, ;EXIT NO WAITING PROCESS
ICMCT0: HLRZ J,T4 ;YES GET THE JOB NUMBER
IFN FTKI10!FTKL10,<
PUSHJ P,SVEUB## ;MAKE THE JOB ADDRESSABLE
>;END OF IFN FTKI10!FTKL10
IFN FTKA10,<
MOVE R,JBTADR##(J) ;GET THE RELOCATION
ADDI T4,(R) ;RELOCATE
>
EXCTUX <HLRZ T3,3(T4)> ;GET THE BYTE COUNT
MOVNS T3 ;NEGATE
HRLZS T3 ;MAKE A COUNTER
EXCTUX <HRRZ T4,3(T4)>;GET THE BUFFER ADDRESS
IFN FTKA10,<
ADDI T4,(R) ;RELOCATE
>
HRLI T4,(POINT 8) ;MAKE A BYTE POINTER
ICMCT1: SOJL P4,ICMCT5 ;END OF MESSAGE
ILDB T1,P1 ;GET A CHARACTER
EXCTUU <IDPB T1,T4> ;STORE THE CHARACTER
AOBJN T3,ICMCT1 ;CONTINUE
ICMCT5: HRRZ T4,SCBCTL##(W) ;GET THE UUO ARG POINTER AGAIN
IFN FTKA10,<
ADDI T4,(R) ;RELOCATE
>
EXCTUU <HRLM T3,3(T4)>;STORE THE STORED BYTE COUNT
MOVEI T1,(J) ;COPY THE JOB NUMBER
PUSH P,W ;SAVE THE NDB POINTER
PUSHJ P,WAKJOB## ;WAKE THE JOB
POP P,W ;RESTORE
SETZM SCBCTL##(W) ;CLEAR THE STATION CONTOL BUSY
JRST CPOPJ1## ;AND EXIT
SUBTTL RQBOOT - AUTO RELOAD OF A DAS80,81,82,DC72 REMOTE STATION
RQBOOT: SKIPGE DEBUGF## ;WAS THE MONITOR LOADED WITH DEBUG
PJRST CPOPJ1## ;YES, THEN NO AUTO DOWN LINE LOAD
MOVEI T1,ST.DDL ;GET DOWN LINE LOAD BIT
TDNE T1,STATES## ;IS SCHED SET?
PJRST CPOPJ1## ;YES, IGNORE THE REQUEST(WILL SEND AGAIN)
HRRZ T1,SCBRQB##(W) ;IS THERE A PENDING BOOT REQUEST?
PJUMPN T1,CPOPJ1## ;NON ZERO SAYS YES, IGNORE IT.
PUSH P,U ;SAVE THE PCB
PUSHJ P,GETLDB ;GET A LINE DATA BLOCK FOR THE FORCE COMMAND
PJRST UPOPJ1## ;NONE AVAILABLE
MOVEI T2,(P4) ;GET THE NUMBER OF BYTES IN THE MESSAGE
ADDI T2,7 ;ROUND UP (+ 1 WORD)
LSH T2,-2 ;TO WORDS
PUSH P,T2 ;SAVE THE SIZE
PUSHJ P,GETZWD ;ALLOCATE SPACE FOR THE MESSAGE
JRST [POP P,T2 ;RESTORE THE SIZE
PUSHJ P,CLRTTY ;FREE THE LDB
JRST UPOPJ1##];EXIT
POP P,T2 ;RESTORE THE SIZE
HRLM T2,(T1) ;STORE THE SIZE
HRLI T1,^D10 ;SET TIMER FOR NET2ND
MOVEM T1,SCBRQB##(W) ;STORE THE POINTER
HRLI T1,(POINT 8,0,35);MAKE A BYTE POINTER TO STORE THE MESSAGE
SETZ T3, ;CLEAR THE COUNTER
RQBOO1: SOJL P4,RQBOO3 ;END OF MESSAGE
ILDB T2,P1 ;GET NEXT CHARACTER
IDPB T2,T1 ;STORE IN THE TEMP BUFFER
AOJA T3,RQBOO1 ;COUNT AND CONTINUE
RQBOO3: HRRZ T1,SCBRQB##(W) ;GET THE ADDRESS BACK
HRRM T3,(T1) ;STORE THE CHARACTER COUNT
PUSH P,W ;SAVE W
MOVEI T1,TTFCXL## ;FORCE RUN THE AUTO LOADER
PUSHJ P,TTFORC## ;WHICH DOES THE BOOT
PUSHJ P,CLRTTY ;MAKE THE TTY AVAILABLE AGAIN
POP P,W ;RESTORE W
PJRST UPOPJ1## ;EXIT AND DISMISS THE MESSAGE
SUBTTL NCSIDC - DEVICE CONTROL FOR INPUT MESSAGES
;SUBROUTINE IDCCTL - DEVICE CONTROL MESSAGES
;CALL MOVEI U,PCB
; MOVEI W,NDB
; MOVEI T1,DLA
; PUSHJ P,IDCCTL
;RETURN JRST INPDIS
IDCCTL: ;ENTRY
;DLA
CAIGE T1,LATLEN## ;CHECK THE LENGTH OF THE LINK ADDRESS
SKIPN F,NETLAT##(T1) ;IS THE DDB DEFINED?
PJSP T1,INCTBD ;NO DLA IS ILLEGAL
HRRZ T2,DEVNET(F) ;CHECK TO MAKE SURE MESSAGE CAME FROM RIGHT NODE
JUMPG F,.+2 ;SKIP IF A DEVICE
HLRZ T2,LDBREM##(F) ;LDB - NDB ADDR IS HERE
CAIE T2,(W) ;BETTER MATCH
PJSP T1,INCTBD ;NOPE, DONT LET MESSAGE BE PROCESSED
IFN FTCMSR,<
MOVE T1,PCBICT(U) ;GET MESSAGE LENGTH
MOVEI T1,-6(T1) ;DISCOUNT PROTOCOL
CAIGE T1,1_<DLHSIZ-1> ;IN RANGE FOR JFFO?
JFFO T1,.+2 ;GET HIGHEST BIT NUMBER
TDZA T1,T1 ;OUT OF RANGE, USE ENTRY 0
MOVNI T1,-^D36(T2) ;IN RANGE, PUT IN PROPER ORDER
AOS NCLRDL(T1) ;RECORD DATA LENGTH
>
PUSH P,F ;SAVE THE DDB ADDRESS/LDB
;CNT
DAPDSP: MOVEI P4,2 ;ALLOW TWO BYTES COUNT
MOVE F,(P) ;RELOAD THE DDB ADDRESS
PUSHJ P,EBI2BI ;GET THE DATA COUNT
JUMPE T1,[POP P,F ;RESTORE F
JRST INPDIS] ;END OF MESSAGE
MOVEI P4,(T1) ;KEEP THE DATA
;TYP
PUSHJ P,EBI2BI ;GET THE IDC TYPE FIELD
CAIL T1,0 ;REALLY BAD
CAILE T1,DC.MAX ;CHECK THE RANGE
JSP T1,[POP P,F ;RESTORE F
PJRST INCTBD] ;DISMISS
JUMPL F,DAPDS2 ;JUST DISPATCH IF TTY
MOVSI S,IOSCON ; DEVICE, SEE IF WE'RE COMPLETELY
TDON S,DEVIOS(F) ; CONNECTED YET/STILL
JSP T1,[POP P,F ;NOPE, DISCARD MESSAGE
PJRST INCTBD]
SKIPA T1,IDCTBL(T1) ;GET DEVICE DISPATCH
DAPDS2: MOVE T1,IDCTTY(T1) ;GET TTY DISPATCH
PUSHJ P,(T1) ;GO TO THE ROUTINE
JSP T1,[POP P,F
PJRST INCTBD] ;ILLEGAL MESSAGE
DAPDS1: JUMPLE P4,DAPDSP ;END OF MESSAGE?
PUSHJ P,EAS2SX ;NO, READ THE REMAINDER
JRST DAPDS1 ;TRY FOR ANOTHER MESSAGE
IDCTBL: ;DISPATCH TABLE FOR DEVICE CONTROL
JRST CPOPJ## ;(0) ILLEGAL MESSGE
JRST IDCDAT ;(1) DATA WITHOUT END OF RECORD
JRST IDCDAR ;(2) DATA WITH END OF RECORD (MTA'S)
JRST IDCSTS ;(3) STATUS
JRST CPOPJ## ;(4) CONTROL MESSAGE - ONLY USED ON TTY'S NOW
JRST IDCUID ;(5) USER ID
JRST IDCFSP ;(6) FILE SPEC
;TTY DEVICE CONTROL DISPATCH TABLE
IDCTTY:
JRST CPOPJ## ;(0) ILLEGAL MESSGE
JRST TTYDAT ;(1) DATA WITHOUT END OF RECORD
JRST TTYDAR ;(2) DATA WITH END OF RECORD (MTA'S)
JRST TTYSTS ;(3) STATUS
JRST TTYCTL ;(4) CONTROL MESSAGE
JRST CPOPJ## ;(5) USER ID
JRST CPOPJ## ;(6) FILE SPEC
SUBTTL IDCDAT (1) DATA WITHOUT END OF RECORD
IDCDAT:
SUBTTL IDCDAR (2) DATA WITH END OF RECORD (MTA'S)
IDCDAR: MOVEI T1,NDPIDT## ;GET INPUT DATA INDEX
HLRZ T2,DEVNET##(F) ;GET NDT ADDRESS
PUSHJ P,@NDTNDP##(T2) ;CALL THE DEVICE ROUTINE
AOS (P) ;SKIP RETURN
NTIDON::MOVEI T1,DEPAIO ;NON, BLOCKING I/O
TDNN T1,DEVAIO(F) ;FOR THIS DEVICE
PJRST NETWAK ;NO, WAKE IT UP
PUSH P,DEVIOS(F) ;SAVE THE REAL DEVIOS
MOVSI S,IO ;GET THE DIRECTION BIT
ANDCAB S,DEVIOS(F) ;SET DIRECTION AS INPUT
PUSHJ P,SETIOD## ;SET IO DONE
POP P,DEVIOS(F) ;RESTORE THE REAL DEVIOS
POPJ P, ;RETURN
SUBTTL IDCSTS (3) STATUS
IDCSTS: MOVEI T1,NDPIST## ;GET STATUS INDEX
HLRZ T2,DEVNET##(F) ; AND NDT
PJRST @NDTNDP##(T2) ;GIVE TO SERVICE ROUTINE
SUBTTL IDCCMN (4) CONTROL MESSAGE
IDCCMN:
POPJ P, ;DISMISS THE MESSAGE
SUBTTL IDCUID (5) USER ID
IDCUID:
POPJ P, ;DISMISS THE MESSAGE
SUBTTL IDCFSP (6) FILE SPEC
IDCFSP:
POPJ P, ;DISMISS THE MESSAGE
;SUBROUTINE DAPHDR - WRITE A NCS/DEVICE CONTROL HEADER
;CALL MOVEI F,DDB
; MOVEI W,NDB
; PUSHJ P,DAPHDR
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;T1=BYTEPOINTER OF THE COUNT FIELD
DAPHDR::TDZA T1,T1 ;CLEAR NCS NEADER BYTE
DAPHDI::MOVEI T1,NCT.IT ;INTERRUPT MESSAGE
PUSH P,T1 ;SAVE THE NCS HEADER FLAG
PUSHJ P,MAKPCB ;MAKE A PCB
PJRST TPOPJ## ;RESTORE T1 AND EXIT
POP P,T1 ;GET THE FLAGS BACK
PUSHJ P,NCSHDR ;WRITE A NCS HEADER
PJRST RMVPCB ;REMOVE THE PCB
LDB T1,NETDLA## ;GET THE DESTINATION LINK ADDRESS
PUSHJ P,BI2EBI ;WRITE
PJRST CPOPJ1## ;EXIT DAP HDR WRITTEN
;SUBROUTINE DAPWRT - WRITE A DATA MESSAGE
;CALL MOVEI F,DDB
; MOVEI U,PCB
; PUSHJ P,DAPWRT OR DAPWRC (FOR DATA COMPRESSION)
;RETURN CPOPJ ;WRITEN
DAPWRB::MOVEI T1,PCV.BN## ;BINARY MODE0
JRST DAPWR0 ;CONTINUE
DAPWRT::TDZA T1,T1 ;ENTRY
DAPWRC::MOVEI T1,PCV.LC## ;LINE PRINTER COMPRESSION
DAPWR0: DPB T1,PCBPCV## ;STORE TYPE
MOVSI T1,PCB.UR## ;GET THE USER DATA FLAG
IORM T1,PCBBLK##(U) ;STORE
PJRST NETWRT ;SEND THE MESSAGE
;SUBROUTINE DAPSST/DAPCST SET AND CLEAR STATUS BITS
;CALL MOVEI T1,BITS ;TO BE CLEARED OR SET
; PUSHJ P,DAPSST/DAPCST
; CPOPJ ;NO CORE
; CPOPJ1 ;MESSAGE SENT
DAPSST::SKIPA T2,[1] ;SET STATUS
DAPCST::MOVEI T2,2 ;CLEAR STATUS
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSH P,T1 ;SAVE STD
PUSH P,T2 ;SAVE STC
PUSHJ P,DAPHDI ;WRITE INTERRUPT HEADER
JRST [POP P,T2 ;RESTORE THE MESSAGE TYPE
PJRST TPOPJ##] ;AND EXIT
;CNT
SETZ P3, ;CLEAR THE COUNT FIELD
IBP P2 ;STEP OVER THE COUNT FIELD
MOVE P1,P2 ;SAVE THE COUNT POSITION
MOVEI T1,DC.STS ;GET STATUS MESSAGE CODE
PUSHJ P,BI2EBI ;WRITE
;STC
POP P,T1 ;GET THE STC
PUSHJ P,BI2EBI ;WRITE
;STD
POP P,T1 ;GET THE STD
PUSHJ P,BI2EBI ;WRITE
;CNT
DPB P3,P1 ;STORE THE COUNT FIELD
AOS PCBOCT##(U) ;UPDATE THE COUNT FIELD
AOS PCBOCT##(U) ;UPDATE THE COUNT FIELD
ADDM P3,PCBOCT##(U) ;UPDATE THE MESSAGE LENGTH
PJRST NETWSR ;WRITE THE MESSAGE
;SUBROUTINE DLYDRQ - DELAY A JOB FOR A DATA REQUEST
;CALL MOVEI F,DDB
; MOVEI W,NDB
; PUSHJ P,DLYDRQ
;RETURNS CPOPJ IF NONBLOCKING I/O
;RETURNS CPOPJ1 IF NORMAL I/O AFTER DATA REQUESTS ARRIVE
DLYDRQ::MOVEI T1,DEPAIO ;GET NON BLOCKINT BIT
TDNE T1,DEVAIO(F) ;IS IT SET
POPJ P, ;YES,EXIT
PUSHJ P,NETHIB ;HIBERNATE
JRST CPOPJ1## ;SEE IF WE HAVE SOME NOW
;SUBROUTINE CHKDRQ - CHECK FOR A DATA REQUEST AND COUNT IT DOWN
;CALL MOVEI F,DDB
; PUSHJ P,CHKDRQ
; POPJ P, ;NO DATA REQUEST ARE AVAILABLE
; CPOPJ1 ;DATA REQUEST AVAILABLE AND COUNTED DOWN
CHKDRQ::CONO PI,PIOFF## ;RACE HERE - WE COULD LET NETDRQ GO NEGATIVE
HRRZ T1,NETDRQ##(F) ;GET THE OUTPUT DATA REQUEST COUNT
JUMPE T1,ONPOPJ## ;NO DATA REQUESTS AVAILABLE
SOS NETDRQ##(F) ;YES, REDUCE IT
CONO PI,PION## ;SAFE NOW
JRST CPOPJ1## ;SKIP RETURN
;SUBROUTINE SETUP - SET UP AC'S F,W,R,J
;CALL PUSHJ P,SETUP
;RETURN CPOPJ
SETUP:: ;ENTRY
LDB J,PJOBN## ;GET THE JOB NUMBER OF THE DEVICE
MOVE R,JBTADR##(J) ;GET THE RELOCATION
HRRZ W,DEVNET##(F) ;GET THE NODE DATA BLOCK POINTE
MOVE S,DEVIOS(F) ;GET IOS
POPJ P, ;RETURN
;SUBROUTINE ONLNDB/OFLNDB - TYPE ONLINE/OFFLINE FOR A NETWORK NODE
;CALL MOVEI W,NDB
; PUSHJ P,ONLNDB/OFLNDB
;RETURN CPOPJ
ONLNDB: SKIPA T1,[[ASCIZ / ON-LINE
/]]
OFLNDB: MOVEI T1,[ASCIZ / OFF-LINE
/]
SKIPGE DEBUGF## ;CHECK FOR DEBUG
POPJ P, ;YES, SKIP THE MESSAGES
PUSH P,U
PUSH P,T1 ;SAVE THE MODE
HRRZ U,OPRLDB## ;GET THE OPERATOR LINE
PUSHJ P,INLMES## ;TYPE %%
ASCIZ /
%%/
PUSHJ P,TYPNDB ;TYPE OUT THE NDB IFO
POP P,T1 ;GET ONLINE/OFFLINE BACK
PUSHJ P,CONMES## ;TYPE IT
PJRST UPOPJ## ;EXIT
;SUBROUTIN TYPNDB - TYPE OUT THE NODE INFOR
;CALL MOVEI U,LDB
; PUSHJ P,TYPENDB
;RETURN CPOPJ
TYPNDB::PUSHJ P,INLMES## ;PRINT MESSAGE
ASCIZ /NODE /
HLRZ T1,NDBSNM##(W) ;GET THE STATION NAME POINTER
MOVE T2,(T1) ;GET THE STATION NAME
SKIPE T1 ;DEFINED YET
PUSHJ P,PRNAME## ;PRINT IT
MOVEI T3,"(" ;PAREN
PUSHJ P,COMTYO## ;PRINT
HLRZ T1,NDBNNM##(W) ;GET THE NODE NUMBER
PUSHJ P,PRTDI8## ;TYPE
PUSHJ P,INLMES## ;TYPE A SEPERATOR
ASCIZ /) /
HRRZ T1,NDBSID##(W) ;GET THE MONITOR NAME
SKIPE T1 ;SKIP IF UNKNOWN
PUSHJ P,CONMES## ;TYPE
PUSHJ P,PRSPC## ;SPACE
HLRZ T1,NDBSID##(W) ;GET THE CREATION DATE
JUMPE T1,CPOPJ## ;EXIT IF UNKNOWN
PJRST CONMES## ;TYPE
SUBTTL COMMON DEVICE DEPENDENT ROUTINES
;HERE ON A CLOSE (OUTPUT) UUO
NETCLO::PUSHJ P,OUT## ;FORCE OUT THE LAST FEW BUFFERS
JFCL ;?? DOES THIS EVER SKIP ??
PUSHJ P,WAIT1## ;MAKE SURE ALL BUFFERS GET WRITTEN
MOVSI S,IOSCLO ;COMMON NETWORK-DEVICE CLOSE BIT
IORB S,DEVIOS(S) ;SET SO WE WON'T TRY TO ADVANCE HIS BUFFERS
; WHEN A "DRQ" MESSAGE COMES IN IN A WHILE
POPJ P,
;COME HERE ON THE RELEASE UUO.
NETRLS::MOVSI S,IOSTBL+IOSERR+IOSHDV ;CLEAR TROUBLE FLAGS
ANDCAM S,DEVIOS(F)
MOVSI S,IOSCON ;IS DEVICE CONNECTED?
TDNN S,DEVIOS(F)
POPJ P, ;NO, NO MORE ACTION REQUIRED
MOVSI S,IOSREL ;YES, SET "RELEASE" BIT IN DEVIOS
IORM S,DEVIOS(F)
POPJ P, ;EXIT
NETHNG::MOVSI S,IOSHDV ;HUNG BIT
IORB S,DEVIOS(F) ;STORE BIT
PUSHJ P,DEVERR## ;DEVICE ERROR
PJRST CPOPJ1## ;EXIT NO MESSAGE
NTDONL::TLNN S,IOSERR+IOSHDV ;OFF LINE?
AOS (P) ;NO
POPJ P, ;RETURN
;SUBROUTINE NET$IN CHECK FOR INPUT READY
;CALL MOVEI F,DDB
; PUSHJ P,NET$IN
;RETURN CPOPJ ;NO
; CPOPJ1 ;YES
NET$IN::CDR$IN::RDA$IN:: ;ENTRY FROM MSGSER
SKIPE T1,NETDEV##(F) ;GET THE LOCATION OF THE MONITOR BUFFERS
JRST NET$I1 ;NO BUFFER
LDB T1,PBUFSZ## ;GET THE BUFFER SIZE
HRLI T1,2 ;NUMBER OF BUFFERS
PUSHJ P,BLDMBF ;BUILD THE BUFFERS
NET$I1: SKIPN MBFBFC(T1) ;ANY DATA PENDING
PJRST DRQMBF ;SEND DATA REQUESTS
JRST CPOPJ1## ;YES, EXIT
SUBTTL TELETYPE DEVICE-DEPENDENT CODE
;DISPATCH TABLE FOR TELETYPES:
REMDSP::JRST D85TYP ;TYPE CHAR IN T3
JRST CPOPJ## ;MODEM CONTROL
JRST CPOPJ## ;ONCE A SECOND STUFF
JRST CPOPJ## ;INITIALIZE
JRST D85CHP ;CHANGE HARDWARE PARMS
JRST D85LPC ;LINE PARM CONTROL
JRST D85ELE ;SET TTY ELEMENT
JRST D85REM ;STUFF FOR REMOTE TTYS
JRST D85OFL ;IS THE LINE DEFINED ON THE STATION
;HERE TO CHECK FOR A LDB BEING ATTACHED TO A NODE
D85OFL: HLRZ T1,LDBREM##(U) ;GET THE NDB POINTER
SKIPE T1 ;IS THERE A NDB
AOS (P) ;YES, SKIP RETURN
POPJ P, ;NO, NON-SKIP RETURN
D85ELE: ;CALL ON ELEMENT CHANGE FOR 2741
PUSHJ P,TTYCHK ;IS IT A CONNECTED TTY
PJRST CPOPJ1## ;NO, DO NOT SET BITS
PUSHJ P,ELEINX## ;CONVERT TO AN INDEX
POPJ P, ;ILLEGAL
DPB T2,LDPELE ;STORE THE ELEMENT NUMBER INDEX
D85EL1: PUSH P,U ;SAVE U
PJRST TTYSET ;SET PARAMETER CHANGE
D85LPC: ;LINE PARAMETER CHANGE
CAIN T3,<LPCUKB>B27 ;UNLOCK KEYBOARD OR TTY INPUT WAIT
PUSHJ P,TTYCHK ;YES, SET IF A TTY
POPJ P, ;NOT CONNECTED IGNORE
MOVSI T1,LRDTIW## ;TI WAIT BIT
TDNE T1,LDBREM##+2(U);IS IT ALREADY SET
POPJ P, ;YES, DO NOT SET IT AGAIN
IORM T1,LDBREM##+2(U);SET IT
SOS (P) ;TTYSET WILL POPJ1 MAKE IT A POPJ
JRST D85EL1 ;COMMON EXIT
IFN FTMODM,<
;HERE FOR MODEM CONTROL FROM SCNSER
D85DSC:: ;ENTRY
PUSHJ P,TTYCHK ;SEE IF A LEGAL TTY
JRST ECOD4## ;NOT A TTY
SKIPL T2,LDBREM##+2(U);IS THIS A DATA SET LINE
JRST ECOD4## ;NO
CAIN T3,DSTSTS## ;STATUS?
JRST D85STS ;YES
CAIN T3,DSTOFF## ;MODEM OFF
JRST D85OFF ;YES,
CAIN T3,DSTON## ;MODEM ON
JRST D85ON ;YES
CAIN T3,DSTCRQ## ;REQUEST DIAL OUT
JRST D85CRQ ;YES
JRST ECOD3## ;NONE OF ABOVE
D85OFF: PUSH P,U ;FOR CALL TO DSCOFF
JRST DSCOFF ;HANG UP PHONE
D85ON: MOVSI T2,LRDDTR ;DATA TERMINAL READY
IORM T2,LDBREM##+2(U) ;SET IT
JRST D85EL1 ;SEND IT
D85CRQ: ;AUTO DIAL
MOVSI T2,LRDADL## ;GET AUTO DIAL LINE BIT
TDNN T2,LDBREM##+2(U);IS THIS A AUTO DIAL LINE
PJRST ECOD4## ;NOPE FAIL
D85CR1: SKIPN DILLDB ;IS THE DIALER AVAILABLE
JRST D85CR2 ;YES, CONTINUE
MOVEI T1,5 ;NO
PUSHJ P,SLEEP## ;SLEEP FOR FIVE SCONDS
JRST D85CR1 ;TRY AGAIN
D85CR2: HRRZM U,DILLDB ;STORE THE LDB OF THE REQUESTER
HRLM J,DILLDB ;STORE THE JOM NUMBER IN THE LEFT HALF
PUSHJ P,GETWRD## ;GET PART ONE OF THE NUMBER
PJRST ECOD3## ;BAD ADDRESS
MOVEM T1,TELNUM ;STORE PART ONE
AOS M ;SECOND PART
PUSHJ P,GETWRD## ;GET SECOND PART
PJRST ECOD3## ;ADDRESS CHECK
TRO T1,17 ;FORCE AN END CHARACTER
MOVEM T1,TELNUM+1 ;STORE PART TWO
MOVEI T2,LRRADL## ;GET AUTO DIAL REQUEST BIT
PUSHJ P,D85TY1 ;SET IT AND CAUSE AN INTERRUPT
D85CR3: MOVEI T1,^D3 ;WAIT FOR THREE SECONDS
PUSHJ P,SLEEP## ;AND THEN CHECK FOR S RESPONSE
SKIPL T1,DILLDB ;CHECK FOR A COMPLETED CALL
JRST D85CR3 ;NO, WAIT AGAIN
SETZM DILLDB ;YES, MAKE THE DIALER AVAILABLE
TLNE T1,200000 ;ERROR BIT UP
JRST CPOPJ1## ;NO, GOOD RETURN
JRST ECOD5## ;GIVE AN ERROR RETURN
D85STS: MOVSI T2,LRDDSR## ;CARRIER ON BIT
TDNN T2,LDBREM+2(U) ;IS IT?
TDZA T1,T1 ;NO
MOVSI T1,DSCHWC## ;YES
JRST STOTC1## ;STORE ANSWER FOR USER
> ;END IFN FTMODM
;COME HERE FROM SCNSER WITH A CHARACTER TO OUTPUT IN T3.
; U POINTS TO THE LDB.
D85TYP: DPB T3,[POINT 9,LDBREM##(U),35] ;SAVE CHAR
PUSHJ P,TTYCHK ;IS LDB ADDRESS VALID?
POPJ P, ;NO, IGNORE.
MOVE T2,LDBREM##+1(U);GET THE STATUS BITS
TRNE T2,STY.DE ;IN DEFERRED ECHO
JRST D85TY3 ;YES
MOVE T2,LDBDCH##(U) ;LOAD SCNSER FLAGS
TLNN T2,LDLECH## ;ANY ECHO BIT ON
JRST D85TY3 ;NO
MOVEI T2,LRRCHP ;YES, GET PARAMETER CHANGE FLAG
IORM T2,LDBREM##(U) ;SET IT
D85TY3: MOVE T2,LDBREM##(U) ;GET THE STATUS AND CHARACTER
TRCE T2,LRRIMO##+1B27 ;CHECK FOR A MODE CHANGE
TRCN T2,LRRIMO##+1B27 ;BOTH IMAGE
JRST D85TY0 ;NO CHANGE
MOVEI T2,LRRIMO## ;YES, FLIP THE BIT IN MEMORY
XORM T2,LDBREM##(U) ;FOR A CHANGE OF STATES
MOVEI T2,LRRCHP## ;GET CHANGE OF PARAMETERS BIT
TROA T2,LRRTTO## ;SET TTY OUTPUT
D85TY0: MOVEI T2,LRRTTO## ;ENTRY FOR NO MODE CHANGE
D85TY1: IORM T2,LDBREM##(U) ;IN LDB
D85RQS: MOVSI T2,.RMSUI## ;STATION NO LONGER IDLE
IORM T2,SCBSTS##(W)
PUSHJ P,NTYSET## ;SET THE TTY BUSY
CONSZ PI,NETIIP## ;AT INTERRUPT LEVEL
POPJ P, ;YES, ALL DONE.
CONO PI,PIOFF## ;TURN OFF THE PI SYS
HRRZM W,NETFLG ;SET THE SOFTWARE INTERRUPT FLAG
CONO PI,REQNET##+PI.ON ;REQUEST AN INTERRUPT
SKIPE NETFLG ;WAIT FOR IT TO HAPPEN
JRST .-1 ;CONTINUE
POPJ P, ;ALL DONE NOW
;SUBROUTINE TO VALIDATE THE LDB ADDRESS IN U.
; SKIP RETURN IF OK. (SCB ADDRESS IN T1)
TTYCHK: EXCH W,(P) ;MUST SAVE W AROUD THE CALL
PUSH P,[WPOPJX##] ;RETURN ADDRESS (WILL HANDLE SKIP RETURN)
PUSH P,W ;SAVE THE CALLER'S ADDRESS
SKIPE W,LDBREM##+4(U) ;IS THERE A SLA AND DLA
HLRZ W,LDBREM##(U) ;POINT TO SCB
JUMPE W,CPOPJ## ;EXIT IF NO STATION OR SLA DLA
LDB T2,LDPLNO## ;YES, GET PHYSICAL LINE NO.
SUBI T2,NETOFS## ;RELOCATE TO A REMOTE LINE
JUMPL T2,CPOPJ## ;NOR IN RANGE
CAIGE T2,M.RTTY## ;CHECK LENGTH
AOS (P) ;OK
POPJ P, ;NO ERROR
;COME HERE ON SPECIAL CALLS FROM SCNSER
;CODE IN T3:
;1 = BUFFER LOW
;2 = CHARACTER NOT STORED
;3 = CONTROL O PROCESSING.
D85REM: CAIL T3,1 ;VALIDATE RANGE
CAILE T3,3
POPJ P, ;IGNORE IF NOT IN RANGE
JRST @.(T3) ;OTHERWISE DISPATCH
EXP TTYBFL ;BUFFER LOW
EXP TTYCNS ;CHARACTER NOT STORED
EXP TTYCTO ;CONTROL O
;THESE ARE NO-OPS FOR NOW.
TTYCNS==CPOPJ##
;COME HERE ON CONTROL O ACTION. THE CONTROL O MAY HAVE BEEN
; SET EITHER ON OR OFF. CHECK THE LDB TO DETERMINE WHICH AND
; SEND A CHARACTER GOBBLER IF IT HAS BEEN SET ON.
TTYCTO: PUSHJ P,TTYCHK ;YES, IS STATION OK?
POPJ P, ;NO, IGNORE.
MOVEI T2,LRRSCG## ;YES, SEND CHAR GOBBLER
; (SCB ADDRESS IN T1)
PUSHJ P,D85TY1 ;REST SAME AS D85TYP.
TTYWAT: MOVEI T2,LRRTTO## ;CHECK FOR CHAR WAITING
TRO T2,LRRTTW##
TDNN T2,LDBREM##(U) ;ANY WAITING?
POPJ P, ;NO.
ANDCAM T2,LDBREM##(U) ;YES, DONT SEND IT
PUSH P,U ;SAVE LDB POINTER
LDB U,LDPLNO## ;GET LINE NUMBER
PUSHJ P,XMTINT## ;GIVE XMT INTERRUPT
PJRST UPOPJ## ;RETURN SCNSER/RMVNDB
;COME HERE ON LINE PARM CONTROL AND CHANGE HARDWARE PARMS.
D85CHP:
PUSHJ P,TTYCHK ;IS LDB ADDRESS VALID? (SET UP T1)
POPJ P, ;NO, IGNORE CALL.
MOVEI T2,LRRCHP## ;YES, FLAG TO CHANGE PARMS
JRST D85TY1 ;SEND STATUS NOW
;HERE IF INPUT BUFFER IS FULL. THIS ROUTINE SETS A BIT TO CAUSE
; THE "XOFF" STATUS MESSAGE TO BE SENT
;SKIP RETURN IF SUCCESSFUL
TTYBFL: PUSHJ P,TTYCHK ;CONNECTED?
POPJ P, ;NO!
AOS (P) ;GIVE SKIP RETURN
MOVEI T2,LRRXOF##+LRRCHP## ;GET THE WANT XOFF FLAG
PJRST D85TY1 ; AND SET IT
NETINT:: ;ENTRY FOR SOFTWARE INTERRUPT
SKIPN NETFLG ;FOR US
JRST NETINT ;NO CONTINUE DOWN THE SKIP CHAIN
CONO PI,CLRNET## ;CLEAR THE INTERRUPT
JSR NETSAV## ;YES, SAVE THE AC'S
MOVEI W,0 ;GET A ZERO TO CLEAR THE FLAG
EXCH W,NETFLG ;LOAD THE NDB AND CLEAR THE FLAG
; PJRST SCNTTO ;SCAN THE TTY'S
;SUBROUTINE SCNTTO - ROUTINE TO OUTPUT TO A TTY
;CALL MOVEI W,NDB
;RETURN CPOPJ
SCNTTO: PUSHJ P,NTYBSY## ;FIND A BUSY TTY
POPJ P, ;NONE EXIT
PUSH P,U ;SAVE THE LDB
PUSHJ P,GETNBP## ;GET A BUFFER FROM THE POOL
JRST UPOPJ## ;NONE THERE
HRRZM U,SCBNBP##(W) ;SAVE THE PCB POINTER
SETZM @PCBOAD(U) ;INDICATE THAT TTYHDR HASN'T BEEN CALLED YET
MOVE U,(P) ;RESTORE THE LDB
PUSHJ P,SCNTT7 ;PROCESS IT
JFCL ;MAY SKIP RETURN
HRRZ U,SCBNBP##(W) ;GET THE PCB POINTER
SKIPN @PCBOAD##(U) ;ANYTHING IN THE BUFFER
JRST SCNTT3 ;NOTHING IN THE BUFFER
PUSHJ P,NETWRT ;SEND THE MESSAGE
JRST SCNTT4 ;COMMON EXIT
SCNTT2: HRRZ U,SCBNBP##(W) ;GET THE PCB POINTER
SCNTT3: SETZM PCBNDB##(U) ;CLEAR THE NDB POINT TO MAKE IT AVAILABLE
SCNTT4: POP P,U ;RESTORE THE LDB
MOVEI T1,LRRIDL## ;GET THE IDL/BUSY BITS AGAIN
TDNN T1,LDBREM##(U) ;STILL BUSY
PUSHJ P,NTYCLR## ;NO, CLEAR THE BUSY FLAG
PUSHJ P,NCSACK ;SEND AN ACK IF NECESSARY
POPJ P, ;RETURN
POPJ P, ;RETURN
;COME HERE WITH LDB ADDRESS IN U WHEN OUTPUT IS FOUND.
SCNTT7: PUSHJ P,SAVE4## ;SAVE THE P'S
MOVE T1,LDBREM##(U) ;GET REMOTE STATION BITS
TRNE T1,LRRXOF## ;XOFF WANTED?
PUSHJ P,TTXXOF ;YES, SEND IT
TRNE T1,LRRSCG## ;CHARACTER GOBBLER WANTED?
PUSHJ P,TTXGBL ;YES, GO SEND IT.
MOVE T1,LDBREM##(U) ;GET REMOTE STATION BITS
TRNE T1,LRRCHP## ;PARM CHANGE NEEDED?
PUSHJ P,TTYCHP ;YES, GO DO IT.
MOVE T1,LDBREM##(U) ;GET REMOTE STATION BITS
TRNE T1,LRRTTO## ;OUTPUT WAITING
PUSHJ P,TTXDAT ;SEND THE DATA
MOVEI T1,LRRADL## ;GET AUTO DIAL BIT
TDNE T1,LDBREM##(U) ;AUTO DIAL REQUEST
PUSHJ P,TTX801 ;YES, SEND THE NUMBER
MOVEI T1,LRREPW## ;IS ECHO PIPELINE MARKER WAITING?
TDNE T1,LDBREM##(U)
PUSHJ P,TTYOKE ;IS IT OK TO LOCAL ECHO?
POPJ P, ;NO. CHECK NEXT LINE.
PJRST TTXEPM ;YES, SEND AN ECHO PIPE LINE MARKER
;COME HERE AT INTERRUPT LEVEL WHEN WE NEED TO CHANGE PARMS.
; LDB ADDRESS IN T2.
TTYCHP: PUSHJ P,SAVE1## ;SAVE THE P'S
TTYCH1: SETZ P1, ;LH = BITS TO SET, RH = CLEAR
PUSHJ P,TTYOKE ;CHECK ON ECHOING MODE
TLO P1,STY.DE ;DEFER ECHO
MOVE T1,LDBDCH##(U) ;CHECK FOR LC TO UC INPUT XLATION
TLNN T1,LDLLCT##
TROA P1,STY.CV ;DONT TRANSLATE
TLO P1,STY.CV ;TRANSLATE
SKIPL LDBPAG##(U) ;OUTPUT STOPPED BY ^S?
TROA P1,STY.XS ;NO.
TLO P1,STY.XS ;YES.
TLNE T1,LDLIMI## ;OR IN IMAGE MODE,
TLOA P1,STY.II ;TELL REMOTE TO SEND EVERYTHING
TRO P1,STY.II ;IF NOT, USE ASCII MODE
MOVEI T1,LRRIMO## ;IMAGE OUTPUT BIT
TDNN T1,LDBREM##(U) ;IMAGE OUTPUT?
TROA P1,STY.IO ;NO
TLO P1,STY.IO ;YES
HRRZ T2,LDBDDB##(U) ;GET THE DDB FOR PIM CHECK
JUMPE T2,TTYCH5 ;NO DDB MEANS NOT PIM
MOVEI T3,PIMMOD ;GET THE "PIM BIT"
TDNN T3,DEVIOS(T2) ;AND SEE IF IT'S SET
JRST TTYCH5 ;IF IT'S NOT, THEN NOT PIM
TRZ P1,STY.II+STY.IO ;IF IT IS, THEN FORCE BOTH IMAGE
TLO P1,STY.II+STY.IO ; INPUT AND IMAGE OUTPUT
TTYCH5: MOVE T1,LDBPAG##(U) ;IS "TTY PAGE" IN EFFECT?
TLNN T1,LPLPAG##
TROA P1,STY.TP ;NO.
TLO P1,STY.TP ;YES.
MOVE T1,LDBDCH##(U)
TLNN T1,LDLXON## ;CHECK "TTY TAPE" BIT
TROA P1,STY.TT ;NOT IN TTY TAPE MODE
TLO P1,STY.TT ;IN TTY TAPE MODE
MOVE T1,LDBDCH##(U)
TLNN T1,LDLTAB## ;HARDWARE TABS?
TROA P1,STY.HT ;NO.
TLO P1,STY.HT ;YES.
TLNN T1,LDLFRM## ;HDW FORM FEEDS
TROA P1,STY.FF ;NO
TLO P1,STY.FF ;YES
TLNN T1,LDLNFC## ;CHECK FOR FREE CR-LF
TROA P1,STY.CR ;YES
TLO P1,STY.CR ;NO
SUBTTL TTYDSC REMOTE DATA SET CONTOL FOR DAS80'S SERIES
SKIPL T1,LDBREM##+2(U);DATA SET LINE
JRST TTYCH4 ;NO CONTINUE
TLNE T1,LRDDTR## ;CARRIER UP
TLOA P1,STY.DT ;YES
TRO P1,STY.DT+STY.RG ;NO
TTYCH4: TLNE T1,LRDTIW## ;INPUT WAIT
TLOA P1,STY.TI ;YES
TRO P1,STY.TI ;NO
SUBTTL TTYSTS/TTYCHR STATUS AND CHARASTICS
PUSH P,P1 ;SAVE STATUS SET & CLEAR BITS
HLRZ T1,0(P) ;BITS TO SET
ANDCM T1,LDBREM##+1(U) ;WILL ANY BITS REALLY BE SET?
JUMPE T1,TTYCH2 ;NO, SKIP SET SECTION
IORM T1,LDBREM##+1(U) ;REMEBER SO WE DON'T SEND AGAIN
PUSHJ P,TTXSST ;SET THE BITS TO SET
TTYCH2: HRRZ T1,0(P) ;GET BITS TO CLEAR
AND T1,LDBREM##+1(U) ;WILL ANY BITS ACTUALLY CLEAR?
JUMPE T1,TTYCH3 ;NO, SKIP CLEAR CODE
ANDCAM T1,LDBREM##+1(U) ;REMEMBER SO WE DON'T SEND AGAIN
PUSHJ P,TTXCST ;SEND THE BITS TO CLEAR
TTYCH3: MOVEI T1,LRRCHP## ;CLEAR PARM SEND BIT
ANDCAM T1,LDBREM##(U)
POP P,T1 ;DISCARD BITS
;COME HERE TO SEND CHARACTERISTICS MESSAGE IF THE CHARACTERISTICS
; HAVE CHANGED.
TTYCH6: MOVSI T1,400000 ;BUILD ENCODED CHARASTICS
LDB T2,LDPFLC## ;GET FILL CLASS
DPB T2,[POINT 4,T1,35] ;BITS 35-32
LDB T2,LDPRSP## ;GET RECEIVE SPEED
DPB T2,[POINT 4,T1,31] ;BITS 31-28
LDB T2,LDPTSP## ;GET TRANSMIT SPEED
DPB T2,[POINT 4,T1,27] ;BITS 27-24
LDB T2,LDPWID## ;GET WIDTH
DPB T2,[POINT 8,T1,23] ;BITS 23-16
LDB T2,LDPACR## ;GET AUTO CRLF POINT
DPB T2,[POINT 8,T1,15] ;BITS 15-8
LDB T2,LDPELE## ;GET THE ELEMNET NUMBER
DPB T2,[POINT 4,T1,7] ;BITS 4-7
MOVE T2,LDBISR##(U) ;GET THE CONTROL BITS
TLNE T2,LILAPL## ;APL MODE
TLO T1,(1B3) ;YES
TLNE T2,LILDBK## ;DEBREAK
TLO T1,(1B2) ;YES
TLNE T2,LILTDY## ;TIDY?
TLO T1,(1B1) ;YES
;BIT 1 NOT USED
EXCH T1,LDBREM##+3(U) ;STORE NEW CHAR., GET OLD
CAME T1,LDBREM##+3(U) ;ANY CHANGE?
PUSHJ P,TTXTCR ;SEND TTY CHARASTICS
POPJ P, ;NO ROOM, TRY LATER
POPJ P, ;LATER
SUBTTL NCS CONTROL MESSAGES
;COME HERE ON DATA REQUEST
TTYDRQ: PUSH P,U ;SAVE THE PCB
TLNE F,LAT.SH## ;SET HOST DISCONNECT PENDING
PJRST UPOPJ## ;YES, IGNORE DRQ
MOVEI U,(F) ;COP THE LDB POINTER
LDB T2,LDPDRQ## ;GET THE CURRRENT DATA REQUEST COUNT
ADD T2,T1 ;FORM NEW SUM
CAILE T2,^D256 ;UNREASONABLE?
PJRST UPOPJ## ;YES, IGNORE THE REQUEST
DPB T2,LDPDRQ## ;STORE THE NEW COUNT
MOVEI T1,LRRTTW## ;IS THIS TTY WAITING?
TDNN T1,LDBREM##(U)
PJRST UPOPJ1## ;NO, RETURN.
ANDCAM T1,LDBREM##(U) ;YES, CLEAR WAITING BIT
MOVEI T1,LRRTTO## ;AND SET OUTPUT BIT
IORM T1,LDBREM##(U)
PUSHJ P,D85RQS ;REQUEST WRVICE ON THE NODE
JRST UPOPJ1## ;THEN RETURN.
SUBTTL DAP CONTROL MESSAGES
TTYCTL: ;SET LDB FIELDS AS FROM "TTY" COMMAND.
PUSH P,U ;SAVE THE PCB
MOVEI U,(F) ;COPY THE LDB POINTER
;DCT
PUSHJ P,EBI2BI ;READ THE TYPE OF CONTROL
CAIN T1,DCT.EP ;ECHO PIPLINE
JRST TTYEPM ;YES
CAIN T1,DCT.CG ;CHARACTER GOBBLER
JRST TTYGBL ;YES,
CAIN T1,DCT.TC ;TTY CHARASTICS
JRST TTYCHR ;YES,
CAIN T1,DCT.AD ;AUTO DIAL
JRST TTYATO ;YES,
JRST UPOPJ## ;NONE OF THE ABOVE EXIT
;DISPATCH TABLE FOR CONTROL MESSAGES
TTYGBL:
TTYATO:
PJRST UPOPJ1## ;NOT IMPLEMENTED
;COME HERE FOR AN ECHO PIPELINE MARKER
TTYEPM:
;CDT
ILDB T1,P1 ;GET THE SERIAL NUMBER
SUBI P4,1 ;REDUCE THE COUNT
DPB T1,LDPEPM## ;STORE THE PIP LINE MARKER
PUSHJ P,TTYOKE ;OK TO ECHO (TEST THE LDB)?
JRST TTYEP2 ;NO, SEND EPM LATER.
MOVEI T2,LRREPW## ;RETURN MARKER AT ONCE
PUSHJ P,D85TY1 ; SINCE DEFERRED ECHO NOT NEEDED
JRST UPOPJ1##
;COME HERE IF THE EPM CANNOT BE SENT RIGHT AWAY.
TTYEP2: MOVEI T1,LRREPW## ;MARK IT AS WAITING
IORM T1,LDBREM##(U)
PJRST UPOPJ1## ;EXIT
;COME HERE FOR CHARASTICS MESSAGE
TTYCHR:
;READ THE TIMES AND IGNORE
REPEAT 6,<
PUSHJ P,EBI2BI ;READ THE TIME
>
PUSHJ P,EBI2BI ;GET THE RECEIVE SPEED
MOVEI T2,(T1) ;COPY TO T2
PUSHJ P,TTCSP1## ;GET THE SPEED INDEX
CAIA ;DON'T SAVE INVALID SPEED
DPB P2,LDPRSP## ;STORE
PUSHJ P,EBI2BI ;GET THE TRANSMIT SPEED
MOVEI T2,(T1) ;COPY THE SPEED
PUSHJ P,TTCSP1## ;GET THE SPEED INDEX
CAIA ;DON'T SAVE INVALID SPEED
DPB P2,LDPTSP## ;STORE
LDB T2,LDPRSP## ;GET THE RECEIVE SPEED BACK
MOVEI T1,LDR274## ;GET 2741 BIT
CAIN T2,(P2) ;RECEIVE AND TRANSMITT THE SAME
CAIE T2,LS0134## ;IS IT AN IBM 2741
SKIPA T2,[ANDCAM T1,LDBDCH##(U)] ;CLEAR THE BIT
MOVE T2,[IORM T1,LDBDCH##(U)] ;SET THE BIT
XCT T2 ;DO IT
PUSHJ P,EBI2BI ;WIDTH OF TTY CHARRIAGE
SKIPE T1
DPB T1,LDPWID## ;STORE
PUSHJ P,EBI2BI ;GET THE AUTO CRLF
SKIPE T1
DPB T1,LDPACR## ;STORE
PUSHJ P,EBI2BI ;READ THE ELEMENT #
MOVE T3,T1 ;COPY TO T3
PUSHJ P,ELEINX## ;GET THE INDEX
SETZ T2, ;ILLEGAL
DPB T2,LDPELE## ;STORE THE ELEMENT NUMBER
PUSHJ P,EBI2BI ;GET THE 2741 BITS
MOVE T2,LDBISR##(U) ;GET THE FLAGS
TRNE T1,CDT.PL ;APL
TLOA T2,LILAPL## ;YES, SET
TLZ T2,LILAPL## ;NO, CLEAR
TRNE T1,CDT.CB ;DEBREAK
TLOA T2,LILDBK## ;YES, SET
TLZ T2,LILDBK## ;NO, CLEAR
TRNE T1,CDT.TD ;TIDY MODE?
TLOA T2,LILTDY## ;YES, SET
TLZ T2,LILTDY## ;NO, CLEAR
HLLM T2,LDBISR##(U) ;STORE THE RESULT
PJRST TTYSET ;SET CHANGE OF PARAMETERS AND EXIT
;COME HERE FOR A TTY DATA MESSAGE. SEND THE CHARACTERS
; TO SCNSER.
TTYDAR: ;DATA WITH END OF RECORD
TTYDAT: PUSH P,U ;SAVE THE PCB
MOVEI U,(F) ;COP THE LDB POINTER
TTYDA1: SOJL P4,[PUSHJ P,NCSACK ;ACK THE MESSAGE
PJRST UPOPJ1## ;EXIT
PJRST UPOPJ1##] ;EXIT
ILDB T3,P1 ;GET NEXT CHARACTER
PUSH P,U ;SAVE THE LINE DATA BLOCK
LDB U,LDPLNO## ;GET LINE NUMBER (LINTAB INDEX)
PUSHJ P,RECINT## ;PROCESS CHARACTER
POP P,U ;RESTORE PCB POINTER
JRST TTYDA1 ;AND PROCESS NEXT CHAR, IF ANY.
;COME HERE FOR A STATUS MESSAGE
TTYSTS: PUSH P,U ;SAVE THE PCB
MOVEI U,(F) ;COP THE LDB POINTER
;STC
PUSHJ P,EBI2BI ;GET THE STATUS CODE
;IGNORE FOR TTY'S
;STY
PUSHJ P,EBI2BI ;GET THE STATUS BITS
HRRM T1,LDBREM##+1(U) ;STORE STATUS BITS
TRNN T1,STY.DE ;DEFERED ECHO MODE?
SKIPA T2,[IORM T3,LDBREM##(U)] ;NO
MOVE T2,[ANDCAM T3,LDBREM##(U)] ;YES
MOVEI T3,LRRLEO## ;SET OR CLEAR LOCAL ECHO BIT
XCT T2
MOVSI T3,LRDTIW## ;GET THE INPUT WAIT BIT
TRNE T1,STY.TI ;STILL IN INPUT WAIT
JRST TTYTIW ;KEY BOARD STILL UN-LOCKED
HLL U,LDBDCH##(U) ;GET THE BITS
SKIPE LDBBKC##(U) ;ANY BREAK CHARACTER IN THE INPUT BUFFER
JRST TTYST1 ;YES, IGNORE CLEAR
TLNE U,LDLCOM## ;AT COMMAND LEVEL
JRST TTYTIW ;YES, DON'T LOCK KEYBOARD
SKIPGE LDBDCH##(U) ;OR OUTPUT IN PROCESS
TTYST1: ANDCAM T3,LDBREM##+2(U);NO, UNLOCK THE KEYBOARD
TTYTIW:
IFN FTMODM,<
SKIPL T2,LDBREM##+2(U);DO WE KNOW IT AS A DATA SET LINE
JRST TTYSET ;NO, IGNORE THE DATA SET BITS
MOVSI T2,LRDDTR ;GET DATA SET READY
TRNE T1,STY.DT ;IS IT
JRST TTYST2 ;YES
TDNE T2,LDBREM+2(U) ;IS THE BIT SET
JRST DSCOFF ;NO
TRNN T1,STY.RG ;IS RING UP
JRST TTYSET ;NO
JRST DSCRNG ;YES
TTYST2: TDNE T2,LDBREM##+2(U);CHECK FOR DATA TERMINAL READY
JRST TTYST3 ;YES
IORB T2,LDBREM##+2(U);NO
MOVSI T2,LRDDSR## ;GET DATA SET READY
ANDCAM T2,LDBREM##+2(U);CLEAR IT
TTYST3: TRNE T1,STY.RG ;IS THERE RING
JRST DSCCRA ;
JRST TTYSET
DSCRNG: MOVE T2,STATES## ;NO, GET THE STATES WORD
TRNE T2,ST.NRL ;CHECK WCHEDULE FOR DATA SETS
JRST TTYSET ;DATA SETS NOT ALLOWED
MOVSI T2,LRDDTR## ;GET DATA TERMINAL READY
IORM T2,LDBREM##+2(U);SET THE STATUS
IFN FTPI,<
MOVEI T3,DSTRNG## ;DATA SET RING
PUSHJ P,DSCSG ;SIGNAL THAT
>
JRST TTYSET ;SET THE BITS
DSCCRA: ;CARRIER ON
MOVSI T2,LRDDSR## ;GET THE CARRIER ON BIT
TDNE T2,LDBREM##+2(U);SEEN BEFORE
JRST TTYSET ;YES
PUSH P,W ;SAVE W
PUSHJ P,TSETBI## ;CLEAR THE INPUT BUFFER
HRRZ T1,DILLDB ;GET THE DIALER LDB
CAIE T1,(U) ;DIAL REQUEST ON THIS LINE
JRST DSCCRB ;NO
MOVSI T2,600000 ;GET BUSY AND ARROR FLAG
IORM T2,DILLDB ;YES, SET THE BUSY FLAGS
JRST DSCCRC ;CONTINUE
DSCCRB: MOVEI T1,TTFCXH## ;GET HELLO INDEX
PUSHJ P,TTFORC## ;FORCE THE COMMAND
DSCCRC: MOVSI T2,LRDDSR## ;GET DATA SET READY
IORM T2,LDBREM##+2(U);SET IT ON
IFN FTPI&FTMODM,<
MOVEI T3,DSTON## ;DATA SET ON
PUSHJ P,DSCSG ;SIGNAL THAT
>
JRST DSCPOW ;COMMON EXIT TO SET BITS
DSCOFF:
IFN FTPI&FTMODM,<
MOVEI T3,DSTOFF## ;DATA SET OFF
PUSHJ P,DSCSG ;SIGNAL THAT
>
DSCOF2: HRRZ T2,DILLDB ;GET THE AUTO DIAL LDB
MOVSI T3,400000 ;GET THE INUSE BIT
CAIN T2,(U) ;THIS LINE
IORM T3,DILLDB ;SET IT
PUSH P,W ;SAVE W
PUSHJ P,RMVTTY ;DETACH THE TTY
DSCOF1: MOVSI T1,LRDCLR## ;CLEAR THE FLAGS
ANDCAM T1,LDBREM##+2(U);CLEAR IT
DSCPOW: POP P,W ;RESTORE W
> ;END IFN FTMODM
TTYSET: MOVEI T1,LRRCHP## ;SEND PARMS IF ANY DISAGREEMENT
IORM T1,LDBREM##(U) ;TO AVOID RACE CONDITION.
PUSHJ P,D85RQS ;CAUSE AN INTERRUPT
;TO BE PENDING FOR THE STATUS
PJRST UPOPJ1## ;EXIT
IFN FTPI&FTMODM,<
DSCSG: PUSH P,T1
PUSH P,F
PUSHJ P,SIGDSC## ;SIGNAL DATA SET STATUS CHANGE
POP P,F
JRST TPOPJ##
>
;SUBROUTINE TO TEST THE LDB AND SKIP RETURN IF LOCAL
; ECHOING SHOULD BE ALLOWED.
;LDB ADDRESS IN P3.
TTYOKE: MOVE T1,LDBREM##(U) ;GET REMOTE STATION BITS
TRNN T1,LRRTTO## ;OUTPUT IN PROGRESS?
TRNE T1,LRRTTW## ;OR WAITING?
POPJ P, ;YES, DONT SEND EPM.
MOVE T1,LDBBY2##(U) ;NO, GET MISC. TTY BITS
SKIPL LDBDCH##(U) ;HAS SCNSER OUTPUT TO DO?
TLNE T1,L2LDEL## ;NO, ARE WE IN RUBOUT SEQUENCE?
POPJ P, ;YES, DONT RETURN EPM.
MOVE T1,LDBDCH##(U) ;GET STATUS BITS
TLNE T1,LDLNEC## ;PROGRAM CONTROL
POPJ P, ;YES
TLNN T1,LDLLCP## ;"NO ECHOING" SPECIFIED?
TLNE T1,LDLBKA## ;OR BREAK ON ALL CHARS?
POPJ P, ;YES, DONT DO LOCAL ECHOING.
JRST CPOPJ1## ;OKAY IF -11 ECHOS.
;SUBROUTINE TTYTCR SEND CHARACTERISTICS MESSAGE.
;CALL MOVEI U,LDB
; PUSHJ P,DTTYTCR
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;MESSAGE SENT
TTXTCR: PUSHJ P,TTYHDI ;NO, SETUP INTERRUPT HEADER
;CNT
PUSH P,P2 ;SAVE THE COUNT POSITION
;TYP
MOVEI T1,DC.CTL ;SET UP CONTROL MESSAGE
PUSHJ P,BI2EBI ;WRITE
;DCT
MOVEI T1,DCT.TC ;TELETYPE CHARASTICS
PUSHJ P,BI2EBI ;WRITE
;CDT
LDB T1,[POINT 2,LDBREM##+3(U),35] ;FILL CLASS
MOVE P1,FILTAB(T1) ;GET POINTER TO CONSTANTS
MOVEI T4,6 ;COUNTER
TTYTC1: ILDB T1,P1 ;GET FILL VALUE
LDB T2,[POINT 4,LDBREM##+3(U),27] ;XMIT SPEED
MOVE T2,LSPTAB##(T2) ;GET SPEED VALUE
SKIPN T2 ;PRESENT?
MOVEI T2,^D110 ;NO, ASSUME 110 BAUD.
MOVEI T3,^D10000 ;COMPUTE BAUD RATE FACTOR
CAIN T2,^D110 ;110 BAUD?
MOVEI T3,^D11000 ;YES, ASSUME 11-UNIT CODE
IMUL T1,T3 ;MULTIPLY BY FACTOR
IDIV T1,T2 ;COMPUTE WAIT TIME IN MS.
PUSHJ P,BI2EBI ;WRITE
SOJG T4,TTYTC1 ;DO FOR ALL SIX TIMES
LDB T1,[POINT 4,LDBREM##+3(U),31]
MOVE T1,LSPTAB##(T1) ;GET RECEIVE SPEED
PUSHJ P,BI2EBI ;WRITE
LDB T1,[POINT 4,LDBREM##+3(U),27]
MOVE T1,LSPTAB##(T1) ;GET TRANSMIT SPEED
PUSHJ P,BI2EBI ;WRITE
LDB T1,[POINT 8,LDBREM##+3(U),23]
PUSHJ P,BI2EBI ;WRITE
LDB T1,[POINT 8,LDBREM##+3(U),15]
PUSHJ P,BI2EBI ;WRITE
LDB T1,LDPELE## ;ELEMENT NUMBER NOT IMPLEMENTED
MOVE T1,ELETAB##(T1) ;GET THE VALUE FROM THE TABLE
PUSHJ P,BI2EBI ;WRITE
MOVEI T1,0 ;IBM 2741 BITS
MOVE T2,LDBREM##+3(U);GET THE 2741 BITS
TLNE T2,(1B3) ;APL MODE
TRO T1,CDT.PL ;YES, SET THE BIT
TLNE T2,(1B2) ;DEBREAK FEATURE
TRO T1,CDT.CB ;YES, SET THE BIT
TLNE T2,(1B1) ;TIDY?
TRO T1,CDT.TD ;YES
PUSHJ P,BI2EBI ;WRITE
PJRST TTXUPD ;UPDATE THE COUNTERS
;TABLES FOR FILL. THE TABLE ENTRIES ARE FOR BS, TAB, LF, VT,
; FF AND CR FROM LEFT TO RIGHT, AND FILL 0-3 FROM TOP
; TO BOTTOM. THE VALUE OF THE ENTRY IS THE NUMBER OF FILL
; CHARACTERS. THIS IS CONVERTED TO MILLISECONDS BY DIVIDING
; BY THE TRANSMIT SPEED OVER 1000. SOMEDAY MAYBE THE USER
; WILL BE ABLE TO SET THE TIMES DIRECTLY, BUT THIS METHOD
; IS USED NOW FOR COMPATABLILTY WITH LOCAL FILLING, WHICH SENDS
; RUBOUTS INSTEAD OF USING TIMEING.
FILTAB: POINT 6,[BYTE (6) 0,0,0,0,00,0] ;CLASS 0
POINT 6,[BYTE (6) 2,2,2,2,14,2] ;CLASS 1
POINT 6,[BYTE (6) 6,0,6,6,25,4] ;CLASS 2
POINT 6,[BYTE (6) 6,2,6,6,25,4] ;CLASS 3
;SUBROUTINE TTYSST/TTYCST SET AND CLEAR STATUS BITS
;CALL MOVEI T1,BITS ;TO BE CLEARED OR SET
; PUSHJ P,TTYSST/TTYCST
; CPOPJ ;NO CORE
; CPOPJ1 ;MESSAGE SENT
TTXSST: SKIPA T2,[1] ;SET STATUS
TTXCST: MOVEI T2,2 ;CLEAR STATUS
PUSH P,T1 ;SAVE STD
PUSH P,T2 ;SAVE STC
PUSHJ P,TTYHDI ;YES, WRITE INTERRUPT HEADER
MOVE P1,P2 ;SAVE THE COUNT POSITION
MOVEI T1,DC.STS ;GET STATUS MESSAGE CODE
PUSHJ P,BI2EBI ;WRITE
;STC
POP P,T1 ;GET THE STC
PUSHJ P,BI2EBI ;WRITE
;STD
POP P,T1 ;GET THE STD
PUSHJ P,BI2EBI ;WRITE
;CNT
DPB P3,P1 ;STORE THE COUNT FIELD
PJRST TTXUP1 ;UPDATE THE COUNTS
;SUBROUTINE TTYCNT - CONNECT A TTY
;CALL MOVEI W,NDB
; PUSHJ P,TTYCNT
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;CONNECT SENT
TTYCNT: ;ENTRY
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSHJ P,SAVJW ;SAVE J AND W
LDB T1,NETCNF## ;GET MCR BYTE
SKIPG T1 ;IF GREATER THAN 0 DON'T CONNECT
SKIPG SCBTTY##(W) ;GET THE TTY CONFIGURATION BACK
IFN FTPI,<
PJRST PSINTC##
>
IFE FTPI,<
POPJ P, ;NO NEW TTY'S
>
SOS J,SCBTTY##(W) ;COUNT THIS TTY
PUSH P,U ;SAVE THE REQUESTING PCB
MOVE T1,J
PUSHJ P,GETLDB ;GET A FREE REMOTE LDB
PJRST UPOPJ## ;NONE AVAILABLE
JRST TTYHCQ ;SKIP THE HOST ENTRY
TTYHCN: PUSHJ P,SAVE4 ;SAVE CONNECT INITATE POINTER
PUSH P,U ;SAVE THE LDB FOR REMOTE CONNECT
TTYHCQ: HLRZ T1,J ;GET THE DLA IF ANY
DPB T1,LDPDLA## ;STORE DLA
SETZ F, ;CLEAR THE DDB POINTER
MOVSI T2,(1B0) ;GET A SIGN BIT
HRRI T2,(U) ;INSERT THE LDB ADDRESS
PUSHJ P,GETSLA ;GET A SOURCE LINK ADDRESS
JRST [PUSHJ P,CLRTTY ;NONE AVAILABLE
PJRST UPOPJ##]
DPB T1,LDPSLA## ;STORE THE SOURCE LINK ADDRESS
PUSH P,U ;SAVE THE LDB
PUSHJ P,NCMHDR ;WRITE A HEADER
JRST [POP P,U ;NO CORE AVAILABLE
PUSHJ P,CLRTTY ;FREE THE LDB
PJRST UPOPJ##]
EXCH U,(P) ;SAVE THE PDB AND GET THE LDB
PUSH P,P2 ;SAVE THE COUNT POSITION
;TYP
MOVEI T1,NC.CNT ;GET CONNECT TYPE
PUSHJ P,BI2EBI ;SEND
;DLA
LDB T1,LDPDLA## ;GET THE DESTINATION ADDRESS
PUSHJ P,BI2EBI ;SEND
;SLA
LDB T1,LDPSLA## ;GET THE SLA
PUSHJ P,BI2EBI ;SEND (FROM THE NETLAT INDEX)
;DPN
MOVEI T1,OBJ.TY ;DESTINATION DEVICE IS A TTY
PUSHJ P,BI2EBI ;SEND
;NAME
LDB T1,LDPRLN## ;GE THE REMOTE PHYSICAL LINE NUMBER
PUSHJ P,BI2EBI ;SEND
;SPN
MOVEI T1,OBJ.TT ;FROM THE TTY HANDLER
PUSHJ P,BI2EBI ;SEND
;NAME
MOVE T1,[SIXBIT/NETSER/]
PUSHJ P,SX2EAS ;SEND
;MML
LDB T1,NDBMML## ;GET THE MESSAGE LENGTH
PUSHJ P,BI2EBI ;SEND
;FEA
;DCM
MOVEI T1,DCM.AS ;ASCII MODE
PUSHJ P,BI2EBI ;SEND
;RNL
MOVEI T1,^D80 ;EIGHTY CHARACTER RECORDS
PUSHJ P,BI2EBI ;SEND
;DTY
MOVEI T1,DTY.MC!DTY.AB!DTY.SB!DTY.27 ;ATTRIBUTES
PUSHJ P,BI2EBI ;SEND
;CNT
POP P,T1 ;GET THE COUNT POSITION BACK
DPB P3,T1 ;STORE THE COUNT
POP P,U ;GET THE PCB POINTER BACK
ADDM P3,PCBOCT##(U) ;STORE THE MESSGE LENGTH
PUSHJ P,NETWRT ;SEND THE MESSAGE
PJRST UPOPJ1## ;RESTORE THE PCB AND EXIT
;SUBROUTINE DSCTTY - DISCONNECT A TTY
;CALL MOVEI T1,DLA
; PUSHJ P,DSCTTY
;RETURN CPOPJ
DSCTTY:
PUSH P,U ;SAVE THE PDB
MOVEI U,(F) ;COPY THE LDB POINTER
PUSHJ P,CLRTTY ;CLEAR THE LDB
PUSHJ P,TTYCNT ;TRY FOR ANOTHER TTY
JRST UPOPJ1## ;EXIT
JRST UPOPJ1## ;EXIT
CLRTTY: LDB T1,LDPSLA ;WERE WE CONNECTED?
JUMPE T1,CLRTY1 ;NO, DON'T TOUCH SCBOPR OR NETLAT
LDB T2,LDPRLN## ;GET THE REMOVE LINE NUMBER
CAIN T2,0 ;IS THIS AN OPR LINE
HLLZS SCBOPR##(W) ;YES, CLEAR THE OPR POINTER
SETZM NETLAT##(T1) ;CLEAR THE POINTER
CLRTY1: PUSHJ P,NTYCLR## ;FORCE TTY TO BE IDLE
SETZM LDBREM##(U) ;CLEAR THE SCB POINTER
PJRST TSETBI## ;CLEAR TYPE AHEAD
;SUBROUTINE TTYCNX - CONNECT TTY CONFIRM MESSAGE
TTYCNX: ;ENTRY FROM ICMCNT
PUSH P,U ;SAVE THE PCB
MOVEI U,(F) ;GET THE LDB POINTER
;SLA
PUSHJ P,EBI2BI ;GET THE SOURCE NODE ADDRESS
DPB T1,LDPDLA## ;STORE AS THE DESTINATION LINK
;DPN
PUSHJ P,EBI2BI ;SKIP THE OBJECT TYPE
;PID
PUSHJ P,EBI2BI ;IGNORE THE NAME
;SPN
PUSHJ P,EBI2BI ;GET THE OBJECT TYPE
;PID
PUSHJ P,EBI2BI ;GET THE PID
CAIA ;SKIP THE HOST ENTRY
TTYHCX: PUSH P,U ;SAVE THE LDB
DPB T1,LDPRLN## ;GET THE REMOTE LINE NUMBER
CAIN T1,0 ;OPERATOR LINE
HRRM U,SCBOPR##(W) ;YES, MAKE HIM THE OPR
;MML
PUSHJ P,EBI2BI ;IGNORE THE LENGTH
;FEA
;DCM
PUSHJ P,EBI2BI ;IGNORE
;RLN
PUSHJ P,EBI2BI ;IGNORE
;DVT
PUSHJ P,EBI2BI ;GET THE FEATURES
TRNN T1,DTY.MC ;MODEM CONTROL ON THIS LINE
TDZA T2,T2 ;NON-DATA SET
MOVSI T2,LRDDSL## ;DATA SET LINE
TRNE T1,DTY.AD ;AUTO DIAL LINE (BELL 801)
TLO T2,LRDADL## ;YES, SET BIT
TRNE T1,DTY.AB ;AUTO BAULD LINE
TLO T2,LRDATO## ;YES, SET THE BIT
TRNE T1,DTY.27 ;IBM 2741
TLO T2,LRD741## ;YES, SET THE BIT
HLLM T2,LDBREM##+2(U);STORE THE BITS
MOVEI T1,LDRDSD## ;JUMP ON DATA SET
JUMPL T2,[IORM T1,LDBDCH##(U) ;REF DS THERE
MOVSI T1,TTVDSD## ;THE 'DSD' BIT
LDB T2,LDPLNO## ;GET LINE NUMBER
IORM T1,LINTAB##(T2) ;SET LORDSD
JRST TTYCNY] ;SET IT
ANDCAM T1,LDBDCH##(U) ;ELSE CLEAR IT
LDB T2,LDPLNO## ;GET LINE NUMBER
MOVSI T1,TTVDSD## ;THE 'DSD' BIT
ANDCAM T1,LINTAB##(T2) ;CLEAR IT
MOVE T2,LINTAB##(T2) ;GET WORD WITH TTVINI IN IT
MOVEI T1,TTFCXR## ;PRINT GREETING ON THE TTY
TLNE T2,TTVINI## ;MONGEN WANTS INITIA RUN
MOVEI T1,TTFCXI## ;YES
PUSHJ P,TTFORC## ;NO, FORCE THE COMMAND
TTYCNY: MOVEI T1,LRRCHP## ;CHARASTICS CHANGE BIT
IORM T1,LDBREM##(U) ;STORE
PUSHJ P,TTYCNT ;TRY FOR ANOTHER CONNECT
JRST UPOPJ1## ;FAILED FOR ANOTHER
JRST UPOPJ1## ;WON ANOTHER TTY
TTYCNZ: ;ENTRY FROM ICMCNN ON A CONNECT
;T1=OBJ T2=SLA
MOVEI T1,ST.NRT ;IS SYSTEM STANDALONE?
TDNE T1,STATES## ;IF SO TTY WILL BE LOST
JRST TTYOT ;STANDALONE
PUSHJ P,SAVJW ;SAVE THE FEK AND NDB
PUSH P,T2 ;SAVE THE SLA
;PID
PUSHJ P,EAS2SX ;SKIP THE NAME
;PID
PUSHJ P,EBI2BI ;READ THE SOURCE OBJECT TYPE
CAIE T1,OBJ.TY ;IS IT A TTY
JRST T2POPJ## ;NO, ILLEGAL
PUSHJ P,EBI2BI ;READ THE REMOTE LINE NUMBER
MOVEI J,(T1) ;COPY TO J
POP P,T2 ;RESTORE THE SLA
HRLI J,(T2) ;PUT IN THE LEFT HALF
PUSHJ P,GETLDB ;GET A LINE DATA BLOCK
POPJ P, ;CAN'T N0NE AVAILABLE
PUSHJ P,TTYHCN ;SEND A CONNECT CONFIRM
POPJ P, ;CAN'T ICMCNN WILL REJECT
MOVEI T1,(J) ;GET THE LINE NUMBER
PJRST TTYHCX ;READ THE REST ON THE MESSAGE
TTYOTP: POP P,T2 ;CLEANUP STACK
TTYOT: SKIPA T2,[RSN.OT] ;SAY NOT AVAILABLE
TTYXN: MOVEI T2,RSN.XN ;SAY CAPACITY EXCEEDED
POPJ P, ;LET ICMCNN SEND DISCONNECT
;SUBROUTINE GETLDB - SEARCH FOR A FREE TTYDDB/LDB
;CALL PUSHJ P,GETLDB
;RETURN CPOPJ ;NO TTY'S FREE
; CPOPJ1 ;FOUND A FREE LDB/DDB U=LDB
GETLDB: ;ENTRY
PUSH P,T1 ;SAVE THE PHYSICAL UNIT NUMBER
MOVE T4,NETRTY## ;GET THE POINTER TO THE REMOTE TTY'S
GETLD1: MOVE U,LINTAB##(T4) ;GET THE LDB POINTER
MOVEI T1,LDRREM## ;GET REMOTE TTY LINE BIT
TDNN T1,LDBDCH##(U) ;IS THIS A REMOTE LINE
JRST GETLD9 ;NO SKIP THE LINE
HLRZ T1,LDBREM##(U) ;GET THE STATION POINTER
JUMPN T1,GETLD9 ;ALREADY ASSIGNED
HRLZM W,LDBREM##(U) ;NO, ASSIGN TO THIS STATION
SETZM LDBREM##+1(U) ;CLEAR THE BLOCK
SETZM LDBREM##+2(U) ;..
SETZM LDBREM##+3(U) ;..
SETZM LDBREM##+4(U) ;..
POP P,T1 ;RESTOE THE REMOTE LINE NUMBER
DPB T1,LDPRLN## ;STORE IN THE LDB
PUSH P,T4 ;SAVE THE LINTAB INDEX
PUSHJ P,LDBINI## ;INITIALIZE THE LDB
MOVSI T1,777740 ;CLEAR THE BAUD SPEED AND FLAGS
ANDCAM T1,LDBISR##(U) ;IN THE LDB
HRL U,(P) ;PUT THE PHYSICAL -10 LINE IN THE LEFT
PJRST TPOPJ1## ;EXIT U=LDB
GETLD9: AOBJN T4,GETLD1 ;CONTINUE
PJRST TPOPJ## ;RESTORE THE UNIT NUMBER AND EXIT
;SUBROUTINE RMVTTY - DETACH A TTY FROM THE JOB
;CALL MOVEI U,LDB
; PUSHJ P,RMVTTY
;RETURN CPOPJ
RMVTTY: PUSHJ P,SAVT## ;SAVE THE TEMP
PUSHJ P,SAVJW ;SAVE F,W
PUSH P,F ;SAVE F
HRRZ F,LDBDDB##(U) ;GET THE DDB
JUMPE F,RMVTT3 ;EXIT IF NO DDB
LDB J,PJOBN## ;GET THE JOB NUMBER
MOVE T1,DEVMOD(F) ;CHARACTERISTICS
TLNE T1,TTYATC ;CONSOLE TTY?
JRST RMVTT1 ;YES, DETACH IT
MOVEI S,IOIMPM!IODERR!IODTER!IOBKTL ;ERROR BITS
IORB S,DEVIOS(F) ;LITE THEM FOR THE OWNER OF THIS TTY
JRST RMVTT2 ;DON'T DETACH TTY BEING USED AS AN I/O DEVICE
RMVTT1: PUSHJ P,TTYDET## ;CALL SCNSER
RMVTT2:
IFN FTPI,<
PUSHJ P,PSIDWN## ;SIGNAL DEVICE DOWN
>
RMVTT3: PUSHJ P,LDBCLR## ;CLEAR BITS THAT 10 BELIEVES ARE TRUE
PUSHJ P,TSETBO## ;THROW AWAY STUFF IN CHUNKS
JRST FPOPJ## ;EXIT
;SUBROUTINE TTXEPM - SEND AN ECHO PIPE LINE MARKER
;CALL MOVEI U,LDB
; PUSHJ P,TTXEPM
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;MESSAGE SENT
TTXEPM:
PUSHJ P,TTYHDI ;NO, SEND A TTY HEADER
;CNT
PUSH P,P2 ;SAVE THE POSITION
;TYP
MOVEI T1,DC.CTL ;CONTROL MESSAGE
PUSHJ P,BI2EBI ;SEND
;DCT
MOVEI T1,DCT.EP ;PIPE LINE MARKER FLAG
PUSHJ P,BI2EBI ;SEND
;CDT
LDB T1,LDPEPM## ;GET THE PIP LINE MARKER
PUSHJ P,DPBBIN ;SEND
;CNT
MOVEI T1,LRREPW## ;EPM NO LONGER WAITING
ANDCAM T1,LDBREM##(U) ;CLEAR
PJRST TTXUPD ;UPDATE THE COUNT
;SUBROUTINE TTXGBL - SEND A CHARACTER GOBBLER
;CALL PUSHJ P,TTXGBL
;RETURN CPOPJ ;MESSAGE SENT
TTXGBL: ;ENTRY
PUSHJ P,TTYHDI ;NO, SEND A HEADER
;CNT
MOVEI T1,2 ;TWO CHARACTER MESSAGE
DPB T1,P2 ;STORE THE COUNT
;TYP
MOVEI T1,DC.CTL ;TELETYPE CONTROL MESSAGE
PUSHJ P,BI2EBI ;SEND
;DCT
MOVEI T1,DCT.CG ;CHARACTER GOBLER CODE
PUSHJ P,BI2EBI ;SEND
MOVEI T1,LRRSCG## ;CHARACTER GOBBLER BIT
ANDCAM T1,LDBREM##(U) ;CLEAR IT
PJRST TTXUP1 ;UPDATE THE COUNTS AND EXIT
;SUBROUTINE TTX801 - SEND A AUTO DIAL MESSAGE TO THE REMOTE DN80
;CALL MOVEI U,LDB
; PUSHJ P,TTX801
;RETURN CPOPJ ;NO CORE
; CPOPJ1 ;MESSAGE SENT
TTX801: ;ENTRY
PUSHJ P,TTYHDI ;SET UP AN INTERRUPT HEADER
;CNT
PUSH P,P2 ;SAVE THE COUNT POSITION
;TYP
MOVEI T1,DC.CTL ;CONTROL MESSAGE
PUSHJ P,BI2EBI ;SEND
;DCT
MOVEI T1,DCT.AD ;AUTO DIAL CODE
PUSHJ P,BI2EBI ;SEND
;CDT
MOVE T4,[POINT 4,TELNUM] ;GET THE POINTER TO THE PHONE NUMBER
TTX802: ILDB T1,T4 ;GET A DIGIT
ADDI T1,"0"+200 ;MAKE EXTENSIBLE ASCII
IDPB T1,P2 ;STORE IN THE MESSAGE
CAIE T1,17+"0"+200 ;IS IT THE END
AOJA P3,TTX802 ;COUNT THE CHARACTER
ADDI P3,1 ;COUNT THE LAST BYTE
TRZ T1,200 ;CLEAR THE CONTINUE BIT
DPB T1,P2 ;RESTORE IT
HRRZ U,DILLDB ;GET THE LDB FOR THE DIAL
MOVSI T1,LRDDTR## ;GET DATA TERMONAL READY
IORM T1,LDBREM##+2(U);SET IT ON
MOVEI T1,LRRADL## ;GET THE AUTO DIAL BIT
ANDCAM T1,LDBREM##(U) ;CLEAR THE REQUEST
JRST TTXUPD ;UPDATE THE COUNT AND EXIT
;SUBROUTINE TTXXOF - ASK REMOTE STATION TO SEND XOFF
;CALL MOVEI U,LDB
; PUSHJ P,TTXXOFF
;RETURN CPOPJ
TTXXOF: PUSHJ P,TTYHDI ;MAKE A HEADER
MOVEI T1,2 ;LENGTH IS 2
DPB T1,P2 ;REMEMBER THAT
MOVEI T1,DC.CTL ; THIS IS A CONTROL MESSAGE
PUSHJ P,BI2EBI ;REMEMBER THAT TOO
MOVEI T1,DCT.XF ;CODE FOR XOFF REQUEST
PUSHJ P,BI2EBI ;SEND THAT
MOVEI T1,LRRXOF## ;GET AND
ANDCAM T1,LDBREM##(U) ; CLEAR THAT BIT
PJRST TTXUP1 ;SEND THE MESSAGE
;SUBROUTINE TTXDAT - SEND A DATA MESSAGE
;CALL PUSHJ P,TTXDAT
;RETURN CPOPJ ;MESSAGE APPENDED TO OUTPUT
TTXDAT: ;ENTRY
LDB T1,LDPDRQ## ;GET DATA REQUEST COUNT
JUMPE T1,TTXDA3 ;NO MORE, DELAY CHARACTER.
SUBI T1,1 ;REDUCE THE COUNT
DPB T1,LDPDRQ## ;STORE THE NEW COUNT
;CNT
PUSHJ P,TTYHDR ;SEND A HEADER
PUSH P,P2 ;SAVE THE COUNT POS
;TYP
MOVEI T1,DC.DAT ;GET THE DAP CODE
PUSHJ P,BI2EBI ;SEND
;DAT
PUSH P,W ;SAVE W PSISER IS BOUND TO DISTROY IT
TTXDA1: LDB T1,[POINT 8,LDBREM##(U),35]
IDPB T1,P2 ;ADD CHARACTER TO STRING
ADDI P3,1 ;INCREMENT STRING LENGTH
MOVEI T1,LRRTTO## ;CLEAR OUTPUT BIT
ANDCAM T1,LDBREM##(U)
PUSH P,U ;SAVE LDB ADDRESS
LDB U,LDPLNO## ;BY SIGNALING AN XMT INTERRUPT
PUSHJ P,XMTINT## ;TO SCNSER
POP P,U ;RESTORE REGISTERS CLOBBERED BY
CAIL P3,NBPBFL## ;ANY ROOM IN MONITOR BUFFER?
JRST TTXDA4 ;NO.
MOVEI T1,LRRSCG## ;SCNSER WANT A CHARACTER GOBBLER
TRO T1,LRRCHP## ;OR PARAMETER CHANGE
TRO T1,LRRXOF## ;OR AN XOFF SENT
TDNE T1,LDBREM##(U) ;
JRST TTXDA4 ;YES EXIT
MOVEI T1,LRRTTO## ;NO, IS ANOTHER CHAR WAITING?
TDNE T1,LDBREM##(U)
JRST TTXDA1 ;YES, APPEND IT TO STRING.
MOVEI T1,LRREPW## ;TRY TO SEND AN ECHO PIPELINE MARKER
IORM T1,LDBREM##(U) ; TO LET THE REMOTE ECHO
TTXDA4: POP P,W ;RESTORE W
HRRZ T1,SCBNBP##(W) ;GE THE PCB POINTER
MOVSI T2,(<NCT.IT>B7) ;GET THE INTERRUPT BIT
ANDCAM T2,@PCBOAD##(T1);CLEAR IT (COUNTS DATA REQ.)
TTXUPD: POP P,T1 ;GET THE COUNT POSITION
DPB P3,T1 ;STORE THE COUNT
TTXUP1: HRRZ T1,SCBNBP##(W) ;GET THE PDB POINTER
ADDM P3,PCBOCT##(T1) ;UPDATE THE PCB
IBP P2 ;SKIP THE NEW COUNT FIELD
SETZ P3, ;CLEAR THE CURRENT COUNT
AOS PCBOCT##(T1) ;COUNT THE COUNT FILED
POPJ P, ;RETURN
;COME HERE IF DATA REQUESTS ARE DEPLETED.
TTXDA3: MOVEI T1,LRRTTW## ;SET WAITING FOR DATA REQUEST
IORM T1,LDBREM##(U) ;IN THE LDB
MOVEI T1,LRRTTO## ;CLEAR THE OUTPUT WAITING
ANDCAM T1,LDBREM##(U) ;IN THE LDB
POPJ P, ;RETURN
;SUBROUTINE TTYHDR - MAKE A PCB FOR TTY OUTPUT
;CALL PUSHJ P,TTYHDR
;RETURN CPOPJ ;U=PCB
TTYHDR: TDZA P1,P1 ;NORMAL MESSAGE REDUCE DATA REQUEST
TTYHDI: MOVEI P1,NCT.IT ;INTERRUPT MESSAGE
PUSH P,U ;SAVE THE LINE DATA BLOCK
HRRZ U,SCBNBP##(W) ;POINT THETHE TTY PCB
SKIPE @PCBOAD##(U) ;WAS THE HEADER WRITTEN
JRST UPOPJ## ;YES
MOVE P2,PCBOAD##(U) ;NO, LOAD THE OUTPUT BYTE POINTER
SETZM PCBOCT##(U) ;CLEAR THE COUNT FIELD
PUSHJ P,NCSTTY ;WRITE THE NCS HEADER
JFCL ;CAN'T FAIL
EXCH U,(P) ;GET THE LDB BACK
LDB T1,LDPDLA## ;GET THE DESTINATION ADDRESS
SETZ P3, ;CLEAR THE COUNT
PUSHJ P,BI2EBI ;SEND
POP P,T1 ;GET THE PCB
ADDM P3,PCBOCT##(T1) ;COUNT THE DLA
SETZ P3, ;CLEAR THE COUNT FIELD
IBP P2 ;SKIP THE <CNT> FIELD
POPJ P, ;EXIT
SUBTTL HOST.U - SET HOST UUO TO SWITCH BETWEEN COMMAND DECODERS
HOST.U:: ;ENTRY FROM COMCON ON SET HOST UUO
PUSHJ P,SAVE4## ;SAVE THE P'S
IFN FTMS,<
PUSHJ P,ONCPU0## ;GET TO CPU 0
>
HRR M,T2 ;LOC OF ARGUMENT
PUSHJ P,GETWDU## ;GET ARG
SKIPE P2,T1 ;COPY THE ARG
PUSHJ P,SRCNDB ;FIND THE NODE
POPJ P, ;NO SUCH NODE
LDB T1,NETCNF## ;SEE IF A MCR
JUMPE T1,CPOPJ## ;NOPE
PUSHJ P,TTYSRC## ;FIND THE USER'S TTY IF ANY
POPJ P, ;NONE
PUSHJ P,TTYCHK ;CHECK FOR A NETWORK TTY
POPJ P, ;NOT LEGAL ON LOCAL TTY'S
AOS (P) ;SET SKIP RETURN
JRST HOSTDT ;GO DETACH THE TTY
SUBTTL HOST.C - SET HOST COMMAND TO SWITCH BETWEEN COMMAND DECODERS
HOST.C::
PUSHJ P,TTYCHK ;CHECK FOR A REMOTE NODE TTY
JRST [MOVEI T1,[ASCIZ /DECsystem-10 TTY's can not be switched via HOST/]
PJRST ERRMES##];TYPE AND EXIT
SKIPN JBTADR##(J) ;ANY CORE ASSIGNED
PUSHJ P,GETMIN## ;NO, ALLOCATE SOME
JUMPE R,DLYCM## ;NO, DELAY THE COMMAND
PUSHJ P,SAVCTX## ;SAVE THE CONTEXT
PUSHJ P,SAVE4## ;SAVE THE P'S
PUSHJ P,CTEXT1## ;GET THE USER'S ARGUMENT
JUMPE T2,NOTENF## ;MUST HAVE A NODE NAME ETC
MOVE P2,T2 ;COPY THE NAME
MOVE T1,T2 ;COPY
PUSHJ P,CVTOCT## ;CHECK FOR A NUMBER
CAIA ;NO WAS A NAME
MOVE P2,T1 ;COPY THE NAME
PUSHJ P,SRCNDB ;FIND THE NDB
JRST [HRRZ T1,NRTUNN ;NO SUCH NODE
PJRST ERRMES##] ;TYPE AN ERROR MESSAGE
LDB T1,NETCNF## ;SEE IF NTE NODE HAS A COMMAND DECODER
JUMPE T1,[MOVEI T1,[ASCIZ /NODE does not support a command decoder/]
PJRST ERRMES##];TYPE THE ERROR
HOSTDT:
PUSH P,U ;SAVE THE LDB
MOVSI T1,JLOG ;GET THE LOGGED IN BIT
TDNE T1,JBTSTS##(J) ;IS THE JOB LOGGED IN
PUSHJ P,TTYDET## ;DET THE TTY
HLRZ P4,NDBNNM##(W) ;REMEMBER WHO WE'RE GOING TO
HLRZ W,LDBREM##(U) ;GET THE OWNER OF THE TTY
HOSTD1: SETZ F, ;CONTROL MESSAGE
PUSHJ P,NCMHDR ;WRITE THE NUMBERED HEADER
JRST [PUSHJ P,NETSLP ;WAIT FOR CORE
JRST HOSTD1] ;TRY AGAIN
PUSH P,P2 ;SAVE THE COUNT BYTE POINTER
MOVEI T1,NC.DSC ;DISCONNECT MESSAGE
PUSHJ P,BI2EBI ;WRITE
;DLA
EXCH U,-1(P) ;SAVE THE PCB RESTORE THE LDB
LDB T1,LDPDLA ;GET THE DESTINATION LINK ADDRESS
PUSHJ P,BI2EBI ;WRITE
;SLA
MOVEI T1,0 ;SLA IS ZERO (EXEC)
PUSHJ P,BI2EBI ;WRITE
;RSN
MOVEI T1,10 ;GET THE REASON AND NODE
PUSHJ P,BI2EBI ;WRITE
MOVE T1,P4 ;GET THE NEW NODE NUMBER
PUSHJ P,BI2EBI ;SEND IT
;CNT
POP P,T1 ;GET THE COUNT FIELD BYTE POINTER BACK
EXCH U,(P) ;SAVE THE LDB RESTORE THE PDB
DPB P3,T1 ;STORE THE COUNT
ADDM P3,PCBOCT##(U) ;STORE THE COUNT
PUSHJ P,NETWRT ;SEND THE MESSAGE
POP P,U ;RESTORE THE LDB
PJRST CLRTTY ;CLEAR OUT THE LDB
SUBTTL LOCAL STORAGE FOR NETSER
$LOW
DILLDB: BLOCK 1 ;LDB WAITING FOR A DIAL REQUEST
TELNUM: BLOCK 2 ;PHONE NUMBER FOR REMOTE DIALER
NETFLG: Z ;CONTAINS A NDB POINTER IF INTERRUPT PENDING
IFN FTCMSR,<
DEFINE SUBTBL(MAX,LOC)<<MAX>B8+LOC-NETGTT>
DLHSIZ==12 ;LENGTH OF HISTOGRAM BLOCKS
NETGTT::
%NTCOR: 0 ;# WORDS OF FREE SPACE NOW IN USE
%NTMAX: 0 ;MAXIMUM %NTCOR HAS GONE
%NTAVG: 0 ;EXPONENTIAL AVERAGE OF %NTCOR * 10^4
%NTBAD: 0 ;# BAD MESSAGES RECEIVED AND IGNORED
%NTRTP: SUBTBL(NCT.TP,NCLRTP)
%NTRMT: SUBTBL(NC.MAX,NCLRMT)
%NTRDL: SUBTBL(DLHSIZ-1,NCLRDL)
%NTXTP: SUBTBL(NCT.TP,NCLXTP)
%NTXMT: SUBTBL(NC.MAX,NCLXMT)
%NTXDL: SUBTBL(DLHSIZ-1,NCLXDL)
%NTBLC: 0 ;LH - PC OF DETECTION OF BAD MESSAGE
;RH - PCB ADDRESS OF BAD MESSAGE
;ADD FIXED-OFFSET ENTRIES ABOVE THIS POINT
NCLRTP: BLOCK NCT.TP+1 ;RECEIVED NCL TYPES
NCLRMT: BLOCK NC.MAX+1 ;RECEIVED NUMBERED TYPES
NCLRDL: BLOCK DLHSIZ ;RECEIVED DATA LENGTHS BY POWERS OF 2
NCLXTP: BLOCK NCT.TP+1 ;TRANSMITTED COUNTER PARTS OF ABOVE
NCLXMT: BLOCK NC.MAX+1
NCLXDL: BLOCK DLHSIZ
;ADD SUBTABLE DATA ENTRIES ABOVE THIS POINT
.NTMXL==:<.-NETGTT-1>_9
> ;END IFN FTCMSR
IFE FTCMSR,< ;SOME DATA IS NECESARY
%NTCOR: 0
%NTBAD: 0
%NTBLC: 0
>
$LIT
NETEND::PRGEND
TITLE NETLPT - NETWORK LINE PRINTER ROUTINES
SEARCH S,NETPRM
$RELOC
$HIGH
NETLPT::ENTRY NETLPT
;LINE PRINTER
SUBTTL DEVICE DATA BLOCKS
;SPECIAL BITS IN LH(S)
IOSCLO==400 ;DEV HAS BEEN CLOSED
IOSREL==1000 ;DEV HAS BEEN RELEASED
IOSUUD==2000 ;UUO PROCESSING DELAYED
IOSCON==4000 ;DEVICE IS CONNECTED
IOSERR==10000 ;ERROR DETECTED AT INT. LEVEL
IOSHDV==100000 ;HUNG DEVICE
;BITS IN LPT IOS STATUS REGISTER
LPTNFF==100 ;SUPPRESSS FORM FEED AT START/END
JRST NTDONL## ;(-5) CHECK IF DEVICE IS ON LINE
POPJ P,0 ;(-4) SPECIAL ERROR STATUS
JRST LPTBFZ ;(-3) BUFFER SIZE
JRST CPOPJ## ;(-2) INITILIATION
JRST NETHNG## ;(-1) HUNG DEVICE
NDEVLP::JRST NETRLS## ;RELEASE
JRST LPTCLS ;CLOSE OUTPUT
JRST LPTOUT ;OUTPUT
JRST ILLINP## ;INPUT
LPTNDP::JRST CPOPJ## ;NO DATA FOR LINE PRINTERS
JRST LPTSTS ;CALL WITH ERROR STATUS
JRST LPTINT ;CALL FROM INTERRUPT LEVEL
LPTBFZ: MOVSI S,IOSHDV
ANDCAB S,DEVIOS(F) ;CLEAR THE BITS
PJRST REGSIZ## ;GET THE BUFFFER SIZE FROM THE DDB
;LPT OUTPUT ROUTINE
LPTOUT: ;CALLED FROM UUOCON
PUSHJ P,SAVE3## ;SAVE THE P'S
PUSHJ P,SETUP## ;SET UP R,W,S
LPTOU1: MOVSI S,IO ;GET THE DIRECTION BIT
IORB S,DEVIOS(F) ;STORE THE BIT
TLNN S,IOSCON ;STILL CONNECTED?
JRST [MOVEI S,IOIMPM!IODERR!IODTER!IOBKTL ;NO, KILL IT
IORB S,DEVIOS(F)
POPJ P,]
PUSHJ P,NTDONL## ;ERROR DETECTED AT INT. LEVEL?
JRST .+2 ;YES, STOP JOB
JRST LPTOU0 ;NO
MOVSI T1,DVOFLN
IORM T1,DEVCHR(F) ;MARK DEVICE OFF LINE
MOVSI T1,DEPADV ;PROTECT CURRENT BUFFER
IORM T1,DEVADV(F) ;IN CASE WE AREN'T BLOCKING
PUSHJ P,HNGSTP## ;STOP JOB OR RETURN
MOVSI T1,DEPADV
ANDCAM T1,DEVADV(F) ;CONTINUED - DON'T HAVE TO PROTECT BUFFER
MOVSI S,IOSHDV ;CLEAR HUNG FLAG
ANDCAB S,DEVIOS(F) ;AND LOAD S
JRST LPTOU1 ;REDO UUO
LPTOU0: TLZN S,IOBEG ;FIRST OUTPUT AFTER INIT
JRST LPTGO ;NO
ANDB S,DEVIOS(F) ;YES, CLEAR IOBEG
PUSHJ P,LPTCRF ;YES PRINT CR FF
LPTGO: MOVEI P1,@DEVOAD(F) ;GET THE POINTER TO THE OUTPUT BUFFER
SKIPG 1(P1) ;EMPTY BUFFER
JRST LPTADU ;YES, ADVANCE TO THE NEXT BUFFER
TLNE S,IOSERR ;ANY ERRORS AT INTERRUPT LEVEL
JRST LPTOFF ;YES, SHUT DOWN THE LPT
PUSHJ P,CHKDRQ## ;ANY DATA REQUESTS
CAIA ;NO, MUST SHUT DOWN
JRST LPTOU2 ;YES, CONTINUE
TRNN S,IOACT ;IS I/O ACTIVE
PUSHJ P,DLYDRQ## ;NO, WAIT FOR A DATA REQUEST
JRST DEVERR## ;SET IOSTBL FOR NON-BLOCKING I/O
JRST LPTOU1 ;TRY AGAIN
LPTOU2: PUSHJ P,DAPHDR## ;MAKE A HEADER/PCB
JRST [TDNE S,[XWD IOSERR,IOACT] ;IS I/O ACTIVE
JRST LPTOFF ;TURN OF THE LPT
PUSHJ P,NETSLP## ;NO, WAIT FOR CORE
JRST LPTOU2] ;TRY AGAIN
TRNN S,IOACT ;IS I/O ACTIVE
PUSHJ P,SETACT## ;NO SET IT ACTIVE
MOVEI P1,@DEVOAD(F) ;GET THE OUTPUT BUFFER BACK
HRRZ T1,1(P1) ;GET THE WORD COUNT
CAILE T1,^D64 ;MAX BUFFER WE WILL ALLOW IS 64 WORDS
JRST [MOVEI S,IOBKTL ; IF HE EXCEEDS THAT, GET AND
IORB S,DEVIOS(F); SET IOBKTL
PUSHJ P,RMVPCB## ; FREE THE PCB
PJRST LPTOFF] ;CLEAR IOACT AND RETURN FROM OUT UUO
IMULI T1,5 ;CONVERT TO BYTES
MOVEM T1,PCBOC2##(U) ;STORE THE BYTE COUNT
ADDI T1,1 ;COUNT THE TYPE FIELD
PUSHJ P,BI2EBI## ;OUTPUT THE COUNT FIELD
MOVEI T1,DC.DAR ;TYPE FIELD DATA WITH EOR
PUSHJ P,BI2EBI## ;WRITE
ADDM P3,PCBOCT##(U) ;UPDATE THE PROTOCOL COUNT
MOVEI T1,2(P1) ;POINT TO THE DATAFIELD
HRLI T1,(POINT 7) ;MAKE A BYTE POINTER
MOVEM T1,PCBOA2##(U) ;STORE THE POINTER
PUSHJ P,DAPWRC## ;SEND THE MESSAGE
POPJ P, ;EXIT
;COME HERE AT INTERRUPT LEVEL WHEN A MESSAGE HAS BEEN SENT BY THE FEK
LPTINT: PUSHJ P,SAVE3## ;SAVE THE P'S
PUSHJ P,SAVJW## ;SAVE J AND W
PUSHJ P,SETUP ;SET UP THE ACS
JRST LPTADV ;YES, ADVANCE THE BUFFER
;COME HERE ON LINE PRINTER STATUS MESSAGE
;SUROUTINE LPTSTS - INTERRUPT THE STATUS MESSAGE
;CALL PUSHJ P,-5 VIA DEVSER(F)
;RETURN CPOPJ
LPTSTS: AOS (P) ;SKIP RETURN
;STC
PUSHJ P,EBI2BI## ;GET THE BINARY STSTUS CODE
;STD
PUSHJ P,EBI2BI## ;GET THE DEVICE STSTUS
HRLM T1,DEVSTS(F) ;STORE THE STATUS
IORM T1,DEVSTS(F) ;OR THE RIGHT HALF
TRNN T1,SLP.OL ;IS THE LPT OFFLINE
JRST LPTST1 ;NO.
;COME HERE IF LINE PRINTER GOES OFF LINE.
TLO S,IOSERR ;SAY LPT IN TROUBLE
TLZ S,IOSTBL ;CLEAR THIS SO SETIOD WILL CALL PSIIOD
; SO HNGSTP IS CALLED
MOVEM S,DEVIOS(F) ;BETTER SAFE THAN CONFUSED!
PUSHJ P,SETIOD## ;START THINGS ROLLING
PUSHJ P,DEVERR## ;SET THE ERROR IN JOB
PJRST NETWAK## ;WAKE THE JOB IF WAITING
;COME HERE IF LINE PRINTER GOES ON LINE AGAIN
LPTST1: MOVSI S,IOSERR
ANDCAM S,DEVIOS(F) ;CLEAR ERROR BITS
PJRST NETWAK## ;WAKE THE JOB IF WAITING
;HERE TO ADVANCE TO THE NEXT BUFFER
LPTADU: MOVSI S,IOSCLO!IOSREL ;UUO LEVEL ENTRY
ANDCAB S,DEVIOS(F) ;SO DEVICE MUST BE OPEN
LPTADV: ;ADVANCE TO THE NEXT BUFFER
TLNN S,IOSCLO ;INTERRUPT FROM A CLOSE
PUSHJ P,ADVBFE## ;NO, ADVANCE
JRST LPTOFF ;NONE LEFT
LPTWCK: HRRZ T1,NETDRQ##(F) ;IF WE CAN'T OUTPUT,
JUMPE T1,.+2 ;THEN DON'T CALL SETIOD. LET ICMDRQ DO IT.
PUSHJ P,SETIOD## ;SET I/O DONE
PUSHJ P,STOIOS## ;STORE IOS
PJRST LPTGO ;TRY ANOTHER BUFFER
LPTOFF:
IFN FTKI10!FTKL10,<
PUSHJ P,RTEVM## ;IF WE HAVE TO STOP BECAUSE OF NO DATA
; REQUESTS, WE HAVE TO RETURN EVM
>
TRNE S,IOACT ;DON'T SAY DONE UNLESS WE REALLY ARE
PUSHJ P,SETIOD## ;SET IO DONE
PJRST CLRACT## ;EXIT THE INTERRUPT
SUBTTL LPTCRF - PRINT A CRLF AS FIRST OUTPUT AFTER INIT
;CALL PUSHJ P,LPTCRF
;RETURN CPOPJ
LPTCRF: ;ENTRY
TLNE S,IOSCON ;ONLY IF REMOTE NODE STILL UP
TRNE S,LPTNFF ;SUPPRESS EXTRA FF
POPJ P, ;RETURN
LPTCR1: PUSHJ P,SAVE4## ;SAVE THE P'S
PUSHJ P,DAPHDI## ;MAKE A HEADER MESSAGE
JRST [PUSHJ P,NETSLP## ;WAIT FOR A BUFFER
JRST LPTCR1] ;TRY AGAIN
MOVEI T2,1 ;GET ONE WORD
PUSHJ P,SLPZWD## ;ALLOCATE
HRLI T1,(POINT 8) ;ASCII BYTE POINTER
MOVEM T1,PCBOA2##(U) ;STORE IN PCB
MOVE T1,[XWD 1,2] ;GET THE COUNT FIELD
MOVEM T1,PCBOC2##(U) ;STORE
MOVSI T1,(BYTE (8)215,214) ;GET A CR FF
MOVEM T1,@PCBOA2##(U) ;STORE IN THE BUFFER
MOVEI T1,3 ;<CNT><TYP><CR><FF>
PUSHJ P,BI2EBI## ;STORE IN PROTOCOL WORD
MOVEI T1,DC.DAR ;DATA WITH END OF RECORD
PUSHJ P,BI2EBI## ;STORE
ADDM P3,PCBOCT##(U) ;STORE THE COUNT
PUSHJ P,NETWRT## ;SEND THE MESSAGE
POPJ P, ;RETURN
;COME HERE ON CLOSE UUO
LPTCLS: PUSHJ P,NETCLO## ;DO NETWORK CLOSE STUFF
PJRST LPTCRF ;WRITE LAST FORM FEED
;HERE ON HUNG DEVICE
$LIT
PRGEND
TITLE NETCDR - NETWORK CARD READER ROUTINES
SEARCH S,NETPRM
$RELOC
$HIGH
NETCDR::ENTRY NETCDR
SUBTTL DEVICE DATA BLOCKS
;SPECIAL BITS IN LH(S)
IOSCLO==400 ;DEV HAS BEEN CLOSED
IOSREL==1000 ;DEV HAS BEEN RELEASED
IOSUUD==2000 ;UUO PROCESSING DELAYED
IOSCON==4000 ;DEVICE IS CONNECTED
IOSERR==10000 ;ERROR DETECTED AT INT. LEVEL
IOSHDV==100000 ;HUNG DEVICE
;BITS IN LH(S) FOR CARD READER
CDR026==400000 ;IN 026 CHARACTER SET MODE
CDREOF==200000 ;WE HAVE SEEN AN EOF CARD
;INTERNAL DATA STORAGE FOR CARD READER BUFFERS
;POINTED TO BY "NETDEV" IN THE DDB
;AND INDEXED BY "P3"
CDRNBF==2 ;NUMBER OF CARD READER BUFFERS
CDRBFL==<^D80/3>+1 ;LENGTH OF THE MONOTOR BUFFER
;CARD READER
JRST NTDONL## ;(-5) SEE IF DEVICE IS ON LINE
POPJ P,0 ;(-4) SPECIAL ERROR STATUS
JRST CDRBFZ ;(-3) BUFFER SIZE
JRST CPOPJ## ;(-2) INITILIATION
JRST NETHNG## ;(-1) HUNG DENETE
NDEVCD::JRST NETRLS## ;(0) RELEASE
JRST ILLOUT## ;(1) CLOSE
JRST ILLOUT## ;(2) OUTPUT
JRST CDRINP ;(3) INPUT
CDRNDP::JRST CDRDAT ;DATA MESSAGE
JRST CDRSTS ;ERROR STATUS FROM INTERRUPT LEVEL
JRST CPOPJ## ;INTERRUPT CALL
CDRBFZ: MOVSI S,IOSCLO+IOSREL+IOSHDV+CDR026+CDREOF
ANDCAB S,DEVIOS(F) ;CLEAR I/O STATUS BITS
MOVSI T1,SCD.SR ;GET READER STOP BIT
ANDM T1,DEVSTS(F) ;CLEAR ALL OTHER BITS
MOVEI T1,^D18 ;ASSUME ASCII.
TRNN M,10 ;C(UUO) IS USER'S INIT ARG.
JRST CDRBF1 ;ASCII.
MOVEI T1,^D27 ;NOT ASCII. ASSUME BINARY.
TRNE M,4 ;BINARY?
JRST CDRBF1 ;YES.
MOVEI T1,^D28 ;MUST BE IMAGE MODE.
CDRBF1: TRZ M,1B29 ;SUPER MODE NOT ALLOWED
POPJ P, ;RETURN WITH BUFFER SIZE
;HERE ON A RELEASE UUO
;CARD READER INPUT ROUTINE
CDRINP: ;ENTRY FROM INPUT UUO
PUSHJ P,SAVE3## ;SAVE THE P'S
CDRINX: PUSHJ P,SETUP## ;LOAD THE ACS
SKIPE P3,NETDEV##(F) ;GET MONITOR BUFFER ADDRESS
JRST CDRIN3 ;BUFFER EXISTS
MOVE T1,[XWD CDRNBF,CDRBFL]; NUMBER,SIZE
PUSHJ P,BLDMBF## ;BUILD THE BUFFERS
MOVE P3,T1 ;LOAD THE POINTER TO THE MBF
CDRIN3: SKIPE MBFBFC##(P3) ;ANY DATA IN MONITOR BUFFERS?
JRST CDRIN2 ;YES, PROCESS IT.
MOVSI S,IO ;SET UP INPUT
ANDCAB S,DEVIOS(F) ;CLEAR THE BIT
TLNE S,IOEND ;END OF FILE
POPJ P, ;YES RETURN TO UUOCON
HRRZ T1,DEVBUF(F) ;IF THE BUFFER THE PROGRAM WANTS FILLED
EXCTUX <MOVE T1,@T1> ; IS ALREADY FULL, RETURN IMMEDIATELY
EXCTUX <SKIPGE @T1> ; SINCE WE MAY HAVE AN INDEFINITE WAIT FOR
PJRST RTEVM## ; THE NEXT MESSAGE
TLNN S,IOSCON ;STILL CONNECTED?
JRST [MOVEI S,IOIMPM!IODERR!IODTER!IOBKTL ;NO, KILL IT
IORB S,DEVIOS(F)
POPJ P,]
PUSHJ P,NTDONL## ;ERROR DETECTED AT INT. LEVEL?
CAIA ;YES
JRST CDRIN4 ;NO, CONTINUE
MOVEI T1,SCD.SR ;GET READER STOP
PUSHJ P,DAPCST## ;CLEAR IT
JFCL
MOVSI T1,DVOFLN
IORM T1,DEVCHR(F) ;MARK DEVICE OFF LINE
PUSHJ P,HNGSTP## ;STOP THE JOB
MOVSI S,IOSHDV ;GET THE HUNG BIT
ANDCAB S,DEVIOS(F) ;CLEAR IT
JRST CDRIN3 ;TRY AGAIN
CDRIN4: PUSHJ P,CDRSRQ ;VIA DATA REQUEST
JRST CDRIN3 ;GO SEE WHY WE CAN'T EXPECT MORE DATA
MOVEI T1,DEPAIO ;DOING ASYNC IO?
TDNE T1,DEVAIO(F)
PJRST RTEVM## ;YES, RETURN TO USER
PUSHJ P,NETHIB## ;NORMAL IO, WAIT FOR DATA
JRST CDRIN3 ;TRY AGAIN
CDRIN2: PUSHJ P,SETACT## ;SET I/O ACTIVE
TLZN S,IOBEG ;FIRST TIME?
JRST CDRGO ;NO.
ANDB S,DEVIOS(F) ;STORE S
MOVSI T2,PCDRAS## ;YES, SET UP BYTE POINTERS
TRNN S,10 ;ASCII?
JRST CDRIN1 ;YES.
MOVSI T2,PCDRBI## ;NO, TRY BINARY OR IMAGE
REPEAT 0,<
TRNE S,100 ;SUPER-IMAGE?
MOVSI T2,PCDRSI## ;YES.
>
CDRIN1: MOVEM T2,DEVOAD(F) ;STORE BYTE POINTER IN DDB
CDRGO: PUSHJ P,NEWBUF## ;INITIALIZE NEW BUFFER
JRST ADRERR## ;ADDRESS CHECK
CDRGO1: MOVE P1,MBFOBC##(P3) ;COMPUTE BUFFER POINTER
IMULI P1,CDRBFL ;BUFFER OFFSET * SIZE
ADD P1,[POINT 12,MBFMBF##(P3)]
MOVEI P2,^D80 ;YES, SET P2 TO COL. COUNT
TRNE S,10 ;ASCII?
JRST CDRNAS ;NO.
ILDB T3,P1 ;GET COL. 1
CAIN T3,4242 ;SWITCH TO 026 CODE?
JRST CRS026 ;YES.
CAIN T3,5252 ;NO, SWITCH TO 029 CODE?
JRST CRS029 ;YES.
CAIN T3,7417 ;EOF CODE?
JRST CRSEOF ;YES.
JRST CDRAS1 ;NO, PROCESS THE CHAR NORMALLY
CDRASC: ILDB T3,P1 ;GET NEXT COL.
;COME HERE TO TRANSLATE 12-BIT CHARACTERS TO ASCII AND PUT THEM
; IN THE USER'S BUFFER. THE CODE TO DO THIS WAS
; TAKEN FROM CDRSRX, HENCE THE PAUCITY OF
; COMMENTS.
CDRAS1: SETZB T1,T2 ;CLEAR T1 AND T2
JUMPE T3,CDRAS2 ;BLANKS ARE VERY SIMPLE
CAIN T3,5000 ;12-0?
MOVEI T3,4242 ;YES, TREAT AS 12-8-2 ([)
CAIN T3,3000 ;NO, 11-0?
MOVEI T3,2202 ;YES, TREAT AS 11-8-2 (!)
LDB T2,[POINT 3,T3,26]
TRNE T3,3 ;DIDDLE T1 AND T2 TO FORM
TRC T2,7 ;INDEXES INTO CHAR TABLE
TRNE T3,74
TRO T2,10
TRNE T3,314
TRO T1,2
TRNE T3,525
TRO T1,1
TLNE S,CDR026 ;IN 026 CHAR SET MODE?
TRO T2,20 ;NO, USE SECOND TABLE
CDRAS2: LDB T3,CRCVPT##(T1) ;GET 7-BIT TRANSLATION
IDPB T3,DEVOAD(F) ;PUT IN USER'S CORE
SOSLE DEVCTR(F) ;ANY ROOM IN USER'S BUFFER?
SOJG P2,CDRASC ;YES, TRANSLATE ANOTHER CHAR
;COME HERE ON END-OF-CARD
CDRENA: MOVEI T1,15 ;INSERT CARRIAGE-RETURN LINE-FEED
IDPB T1,DEVOAD(F) ;IN USER'S BUFFER
MOVEI T1,12 ;TO MARK THE END OF THE CARD
IDPB T1,DEVOAD(F)
JRST CDRDON ;DONE WITH CARD.
;COME HERE TO DO SPECIAL PROCESSING FOR COL. 1.
CRS026: SKIPA T1,[IORB S,DEVIOS(F)]
CRS029: MOVE T1,[ANDCAB S,DEVIOS(F)]
MOVSI S,CDR026 ;LOAD 026 BIT
XCT T1 ;SET OR CLEAR IT AS REQ'D
JRST CDRIGN ;IGNORE THE CARD OTHERWISE
;COME HERE ON END-OF-FILE INDICATION
CRSEOF: MOVSI S,CDREOF ;SET EOF PENDING BIT
IORB S,DEVIOS(F)
JRST CDRIGN ;AND IGNORE REST OF CARD
;COME HERE IF THE MODE IS NOT ASCII.
CDRNAS: TRNN S,4 ;IMAGE MODE?
JRST CDRIMG ;YES, NO SPECIAL PROCESSING
ILDB T1,P1 ;GET COL. 1
SOS P2 ;DECREMENT COL. COUNT
MOVEI T2,-5(T1) ;7-9 PUNCH?
TRNE T2,17
TRO S,IOIMPM ;NO, SET ERROR BIT
LSH T1,-6 ;COL'S 12-3 ARE WORD COUNT
JUMPE T1,CDRIGN ;IGNORE IF WC = 0
MOVE T3,T1 ;COPY WORD COUNT
IMULI T3,3 ;COMPUTE BYTE COUNT
CAMGE T3,DEVCTR(F) ;TOO MUCH FOR USER'S BUFFER?
MOVEM T3,DEVCTR(F) ;YES, SHORTEN AMOUNT
HRRM T1,@DEVOAD(F) ;PUT WC IN RH OF FIRST BUFFER WORD
ILDB T1,P1 ;GET COL. 2 (CHECKSUM)
SOS P2 ;DECREMENT COL. COUNT
MOVSM T1,MBFCHK##(P3) ;STORE IN DDB
HRLM T1,@DEVOAD(F) ;AND IN LH OF WORD COUNT WORD
CDRBIN: ILDB T1,P1 ;FETCH CHARACTER
IDPB T1,DEVOAD(F) ;PUT IN USER'S BUFFER
SOSLE DEVCTR(F) ;ROOM LEFT?
SOJG P2,CDRBIN ;YES
;COME HERE AT THE END OF A BINARY CARD
CDRENB: MOVEI T2,@DEVIAD(F) ;BUFFER ADDRESS
PUSHJ P,CKS12## ;COMPUTE CHECKSUM
CAME T1,MBFCHK##(P3) ;MATCH?
TRO S,IODTER ;NO. SIGNAL ERROR.
JRST CDRDON ;DONE WITH CARD.
;COME HERE ON IMAGE MODE.
CDRIMG: MOVEI T1,@DEVIAD(F) ;BUFFER POINTER
MOVEI T2,2(T1) ;START OF DATA
HLRZ T1,0(T1) ;BUFFER LENGTH
CAILE T1,CDRBFL ;LONGER THAN A CARD?
MOVEI T1,CDRBFL ;YES, SHORTEN
MOVE T3,T1 ;SAVE BUFFER LENGTH
ADDI T1,-1(T2) ;POINT T1 TO END OF BUFFER
HRLI T2,@P1 ;BUILD BLT WORD
BLT T2,(T1) ;MOVE DATA TO USER CORE
ADDM T3,DEVOAD(F) ;INCREMENT DEVOAD AS THOUGH BY IDPB'S
;FALL INTO CDRDON
;COME HERE WHEN THE CARD IS DONE
CDRDON: MOVEI T1,@DEVOAD(F) ;LAST ADDRESS
MOVEI T2,@DEVIAD(F) ;FIRST ADDRESS - 1
SUBI T1,1(T2) ;COMPUTE NUMBER OF WORDS STORED
HRRM T1,1(T2) ;STORE IN FIRST WORD OF BUFFER
PUSHJ P,SETIOD## ;SET I/O DONE
PUSHJ P,ADVBFF## ;ADVANCE BUFFERS
TRZ S,IOACT ;NONE--I/O NO LONGER ACTIVE
PUSHJ P,AVOMBF## ;ADVANCE THE OUTPUT BUFFER
CAIA ;NO, DATA IN THE BUFFER
TRNE S,IODERR+IOIMPM+IODTER ;ANY ERRORS?
TRZ S,IOACT ;YES (OR NO MORE BUFFERS),
; NO MORE UNTIL NEXT UUO
PUSHJ P,STOIOS## ;RESET HUNG DEVICE COUNT
TRNE S,IOACT ;IS I/O STILL ACTIVE?
JRST CDRGO ;YES, DO ANOTHER BUFFER
;COME HERE WHEN I/O GOES INACTIVE FOR ANY REASON.
; IF THERE HAVE BEEN NO ERRORS, ATTEMPT TO KEEP THE MONITOR BUFFERS
; FULL. IF THERE HAVE BEEN ERRORS, TAKE BACK DATA REQUESTS.
IFN FTKI10!FTKL10,<
PUSHJ P,RTEVM## ;RETURN ANY EVM
>
PUSHJ P,CDRSRQ ;SEND DATA REQUESTS IF DEVICE OK
POPJ P, ;LET NEXT CDRIN4 CALL HANDLE ERRORS
POPJ P, ;BACK TO UUOCON
CDRIGN: PUSHJ P,AVOMBF## ;ADVANCE THE OUTPUT BUFFER
CAIA ;CHECK FOR ANOTHER CARD/DATA REQUEST
JRST CDRGO1 ;YES, PROCESS THE CARD
PUSHJ P,CLRACT## ;THIS MUST BE OFF NOW IN CASE WE HAVE
JRST CDRINX ; NO MORE CARDS AND HAVE TO RETURN TO UUOCON
;COME HERE IF THE USER ISSUES AN INPUT UUO AND THE BUFFERS
; ARE EMPTY OR RIGHT AFTER TAKING SOME DATA FROM THE BUFFERS.
; ISSUE DATA REQUESTS IF REQUIRED TO KEEP THE MONITOR BUFFERS
; FILLED. IF THE BUFFERS ARE EMPTY IT IS LEGITIMATE TO CHECK
; THE STATUS REGISTER FOR UNUSUAL CONDITIONS.
CDRSRQ: SKIPE MBFBFC##(P3) ;ANY DATA LEFT IN MONITOR?
JRST CDRSR2 ;YES, PROCESS IT.
HLRZ T1,DEVSTS(F) ;NO, GET STATUS
TRNN T1,SCD.ME!SCD.CZ!SCD.HZ ;ERROR OR END-OF-FILE?
JRST CDRSR2 ;NO, SEND DATA REQUESTS
TRNN T1,SCD.HZ!SCD.CZ ;YES, END-OF-FILE?
JRST CDRSR3 ;NO. CHECK FOR TROUBLE.
;COME HERE ON END-OF-FILE DETECTION
TLO S,IOEND!IOBEG ;TELL UUOCON WE HAVE EOF
TLZ S,IOSERR!IOSTBL!CDREOF ;CLEARUP ERROR BITS
PJRST STOIOS## ;RETURN
;COME HERE ON TROUBLE
CDRSR3: TRNN T1,SCD.OR ;OVERRUN?
JRST CDRSR4 ;NO, LET OPR TRY TO RECOVER
MOVEI S,IODERR ;SET DEVICE ERROR BIT
IORB S,DEVIOS(F)
CDRSR4: MOVSI S,IOSERR+IOSTBL ;SET ERROR BITS FOR UUO LEVEL
IORB S,DEVIOS(F)
IFN FTKI10!FTKL10,<
PUSHJ P,SVEVM## ;SAVE THE EVM OVER THE CALL TO DEVERR
>;END FTKI10!FTKL10
PJRST DEVERR## ;MAKE UUO LEVEL CALL HNGSTP
;COME HERE IF THERE ARE NO INTERESTING STATUS BITS TO
; LOOK AT.
CDRSR2: PUSHJ P,DRQMBF## ;SEND THE DATA REQUESTS
;COME HERE WHEN DATA REQUEST HAS BEEN TAKEN CARE OF
CDRSR1: MOVE S,DEVIOS(F) ;GET DEVIOS
; TRNE S,IOACT ;IS IO ACTIVE
; SKIPE MBFBFC(P3) ;YES, IS THERE ANY DATA?
; POPJ P, ;I/O NOT ACTIVE OR DATA PRESENT
CDRSR7: HLRZ T1,DEVSTS(F) ;GET LATEST STATUS
TRNN T1,SCD.SR ;HAS READING STOPPED
JRST CPOPJ1## ;NO
MOVEI T1,SCD.SR ;GET OFF-LINE BIT
PUSHJ P,DAPCST## ;CLEAR THE STATUS BIT
JRST CPOPJ1## ;WAIT FOR THE DATA
MOVSI T1,SCD.SR ;YES, CLEAR CARD READ STOP BIT
ANDCAM T1,DEVSTS(F) ;SO WE WONT SEND MSG AGAIN
PJRST CPOPJ1##
;COME HERE ON CARD READER STATUS MESSAGE
;SUBROUTINE CDRSTS - STATUS MESSAGE RECEIVED
;CALL PUSHJ P,-5 VIA DEVSER(F)
;RETURN CPOPJ
CDRSTS: AOS (P) ;SKIP RETURN
;STD
PUSHJ P,EBI2BI## ;GET THE BINARY CODE
;STC
PUSHJ P,EBI2BI## ;GET THE DEVICE STATUS
HRLM T1,DEVSTS(F) ;STORE THE STATUS
IORM T1,DEVSTS(F) ;OR IN THE RIGHT HALF
MOVSI S,IOSERR!IOSTBL!IOSHDV ;IN CASE WE ARE ONLINE
TRNN T1,SCD.ME ;ANY ERROR?
ANDCAM S,DEVIOS(F) ;NO,CLEAR ERROR BITS
PJRST NTIDON## ;WAKEUP THE JOB
;COME HERE ON CARD READER DATA MESSAGE
CDRDAT: SKIPN P3,NETDEV##(F) ;GET THE BUFFER AREA
POPJ P, ;IGNORE THE DATA
MOVE P2,MBFIBC##(P3) ;COMPUTE BUFFER LOCATION
IMULI P2,CDRBFL
ADDI P2,MBFMBF##(P3) ;ADD THE OFFSET
HRLI P2,(POINT 12) ;COLUMN BYTE POINTE
MOVEI T1,1(P2) ;CLEAR THE BUFFER
HRLI T1,(P2) ;WITH A BLT POINTER
SETZM (P2)
BLT T1,CDRBFL-1(P2) ;CLEAR IT
;COPY THE DATA TO THE MONITOR BUFFER (12 COL _8 BIT)
CDRCV1: SETZ T4, ;CLEAR REPEAT COUNT
CDRCV0: SOJL P4,CDRDA1 ;END OF DATA
ILDB T1,P1 ;GET THE NEXT BYTE
TRZN T1,200 ;CHECK FOR 1CCCCCCC
JRST CDRCV2 ;NO
IDIVI T1,20 ;SEPERATE THE ZONES
LSHC T2,-2 ;COMPUTE THE INDEX TO THE CONVERSION TABLE
TLZN T3,(1B0) ;CHECK WHICH HALF
SKIPA T2,CDRCTB(T2) ;GET THE LEFT HALF
HRLZ T2,CDRCTB(T2) ;NO RIGHT HALT
TLZE T3,(1B1) ;WHICH QUARTER
LSH T2,11 ;LOW QUARTER
LSHC T1,-33 ;GET THE WHOLE COLUMN
JRST CDRCV5 ;STORE THE BYTE
CDRCV2: TRZN T1,100 ;REPEAT OF BLANKS
JRST CDRCV3 ;NO
SOJL T1,CDRCV1 ;REDUCE COUNT OF BLANKS
IBP P2 ;SKIP FOR A BLANK
JRST .-2 ;CONTINUE
CDRCV3: TRZN T1,40 ;REPEAT COUNT
JRST CDRCV4 ;NO
MOVEI T4,(T1) ;YES, COPY THE REPEAT COUNT
JRST CDRCV0 ;TRY AGAIN
CDRCV4: TRNE T1,20 ;CHECK FOR RESERVED OF 12 BIT BYTES
JRST CDRCV1 ;RESERVED IGNORE
MOVEI T2,(T1) ;COPY TO T2
LSH T2,10 ;MAKE ROOM FOR SECOND HALT
SOJL P4,CDRDA1 ;END OF DATA
ILDB T1,P1 ;GET THE NEXT BYTE
IORI T2,(T1) ;INSERT
CDRCV5: IDPB T2,P2 ;STORE THE OUTPUT BYTE
SOJG T4,CDRCV5 ;CHECK FOR A REPEAT COUNT
JRST CDRCV1 ;GET NEXT BYTE
CDRDA1: PUSHJ P,AVIMBF## ;ADVANCE THE INPUT MONITOR BUFFER
HRLZI T1,-1 ;DECREMENT THE DATA REQ'S
ADDM T1,NETDRQ##(F) ;IN THE DDB
POPJ P, ;END OF PROCESSING.
;CONVERSION TABLES
CDRCTB:
BYTE (9)000,400,200,100
BYTE (9)040,020,010,004
BYTE (9)002,001,202,102
BYTE (9)042,022,012,006
$LIT
END