1 2 040000 %BEGIN 3 %CONTROL K'101011' 4 %CONSTINTEGER CSIZE = 2231 5 %CONSTINTEGER BLIMIT = 14 6 %CONSTINTEGER INIT DISPLAY = 255 7 %CONSTINTEGER READ DISPLAY = 254 8 %OWNINTEGER MYNODE = 4; !OUR NODE NUMBER 9 %OWNINTEGER THRESHOLD = 150; !ROUTING THRESHOLD 10 %OWNINTEGER LFACTOR = 8; !BUFFERS PER SCORE INCREMENT 11 %OWNINTEGER BC = 0; !NO. OF BUFFERS ALLOCATED 12 %OWNINTEGER BL = 9999; !CONNECT BUFFERS FOR NODE 13 %OWNINTEGER AL = 255; !CONNECT BUFFERS PER ATTACHMENT 14 %RECORDFORMAT CADDRF(%INTEGER LINK) 15 %OWNRECORD (CADDRF) %ARRAYNAME CADDR 16 %OWNINTEGER CLIMIT = CSIZE 17 %OWNINTEGER DISPLAY SERVICE = 0 18 %OWNINTEGER BUFFINDEX = 0 19 %OWNINTEGER BUFFLIMIT = BLIMIT 20 %OWNINTEGER BUFFLOST = 0 21 %RECORDFORMAT BUFFF(%BYTEINTEGER USE, LINE, %BYTEINTEGERARRAY %C 22 PACKET(0:21)) 23 %OWNRECORD (BUFFF) %ARRAYNAME BUFFADDR 24 %OWNRECORD (BUFFF) %ARRAY BUFFER(0:BLIMIT) 25 %CONSTINTEGERNAME COMM AREA = K'140002' 26 %CONSTINTEGER WW = 15 27 %CONSTINTEGER PMAC = 6 28 %CONSTINTEGER MAXLINE = 31 29 %CONSTINTEGER MINADDR = X'8000' 30 %CONSTINTEGER MAXADDR = X'7FFF' 31 %CONSTINTEGER ROUTEADDR = X'7FFF' 32 %CONSTINTEGER TERM255 = X'7F00' 33 %CONSTINTEGER MAXPOLL = 500; !10 SECONDS 34 %CONSTINTEGER REQUEST BUFFER = 0 35 %CONSTINTEGER RELEASE BUFFER = 1 36 %CONSTINTEGER LINE INPUT = 1 37 %CONSTINTEGER LINE OUTPUT = 2 38 %CONSTINTEGER BOUNCE LINE = 3 39 %CONSTINTEGER TAKE LINE DOWN = 4 40 %CONSTINTEGER BRING LINE UP = 5 41 %CONSTINTEGER KERNEL SERVICE = 29 42 %CONSTINTEGER BUFFER MANAGER = 17 43 %CONSTINTEGER CONTROL SERVICE = 11 44 %CONSTINTEGER CLOCK = 0 45 %CONSTINTEGER ATTACHFN = 1 46 %CONSTINTEGER REMOVEPFN = 8 47 %CONSTINTEGER CLOCKFN = 10 48 %CONSTBYTEINTEGERNAME OWNID = K'160030' 49 %PERMINTEGERFNSPEC SVC(%INTEGER EP, B, C) 50 %SYSTEMROUTINESPEC ALARM(%INTEGER TICKS) 51 %SYSTEMROUTINESPEC LINKIN(%INTEGER SERVICE) 52 %CONSTINTEGERNAME INT = K'160060' 53 %CONSTBYTEINTEGERNAME CHANGE OUT ZERO = K'160310' 54 %CONSTINTEGER T3SERVICE = 21 55 56 57 %RECORDFORMAT LCPF(%RECORD (LCPF) %NAME LINK) 58 %RECORDFORMAT LCPXF(%INTEGER LINK) 59 %RECORDFORMAT LAPF(%RECORD (LAPF) %NAME PLINK, GLINK) 60 %RECORDFORMAT CPF(%RECORD (LCPF) %ARRAY LINK(0:1), %C 61 %RECORD (LCPF) %ARRAY PTR(0:1), %INTEGERARRAY ADDR(0:1), %C 62 %INTEGER NODE, STATE, %BYTEINTEGERARRAY CNTL, LIM, STA, LINE(0:1), %C 63 %INTEGER SEQNO, ERROR, %INTEGERARRAY BLOCKS, BYTES, %C 64 REPLIES, NT(0:1)) 65 %RECORDFORMAT APF(%RECORD (APF) %NAME PLINK, GLINK, %INTEGER %C 66 LOW, HIGH, NODE, SCORE, LINE, PROC, LIMIT, BUFFS, %BYTEINTEGER %C 67 STATUS, POLL, %RECORD (LCPF)CPTR, %INTEGER SEQNO, NT, %C 68 MESSIN, CFIN, COKIN, BLKIN, MESSOUT, CFOUT, COKOUT, BLKOUT) 69 %RECORDFORMAT MPF(%RECORD (MPF) %NAME LINK, %BYTEINTEGER LEN, %C 70 TYPE, FN, SF, %INTEGER ADDR1, %BYTEINTEGER NODE1, NODE2, %C 71 %INTEGER ADDR2, %BYTEINTEGER SFLAGS, UFLAGS, %C 72 %BYTEINTEGERARRAY DATA(0:255)) 73 %RECORDFORMAT MPXF(%RECORD (MPXF) %NAME LINK, %BYTEINTEGER LEN %C 74 , TYPE, FN, SF, %INTEGER ADDR, %BYTEINTEGER SFLAGS, UFLAGS, %C 75 %BYTEINTEGERARRAY DATA(0:255)) 76 %RECORDFORMAT PF(%BYTEINTEGER SERVICE, REPLY, FN, LINE, %C 77 %RECORD (MPF) %NAME MES, %BYTEINTEGER LEN, SPARE) 78 %RECORDFORMAT DUMMYF(%RECORD (DUMMYF) %NAME LINK, %BYTEINTEGER %C 79 LEN, TYPE, FN, SF, %INTEGER ADDR1, %BYTEINTEGER NODE1, NODE2 %C 80 , %INTEGER ADDR2, %BYTEINTEGER SFLAGS, UFLAGS) 81 %CONSTRECORD (LCPF) %NAME NULL = 0 82 %CONSTRECORD (LCPF) %NAME EMPTY = -1 83 84 85 %ROUTINESPEC ACBGET(%INTEGER FLG) 86 %ROUTINESPEC CCBGET(%INTEGER FLG) 87 %ROUTINESPEC ISSUE(%INTEGER F, Q) 88 %ROUTINESPEC ACBASSIGN(%INTEGER P) 89 %ROUTINESPEC ACBFREE(%RECORD (APF) %NAME AP) 90 %ROUTINESPEC CCBASSIGN(%INTEGER S) 91 %ROUTINESPEC CCBFREE(%INTEGER NS) 92 %ROUTINESPEC SETUPQUOTE(%RECORD (APF) %NAME PP, %RECORD (MPF) %C 93 %NAME QQ, %INTEGER REPLY) 94 %INTEGERFNSPEC SCORE(%RECORD (APF) %NAME TAP) 95 %RECORD (LCPF) %MAPSPEC GET 96 %ROUTINESPEC FREE(%RECORD (LAPF) %NAME II) 97 %CONSTINTEGERNAME ATTACHES = K'060140' 98 %CONSTINTEGERNAME CONNECTS = K'060142' 99 %CONSTINTEGERNAME NIFS = K'060144' 100 %CONSTINTEGERNAME ERRORS = K'060146' 101 %CONSTINTEGERARRAYNAME COUNTS = K'060142' 102 %SWITCH COM(0:10) 103 %SWITCH NSW(1:7) 104 %SWITCH RSW(1:7) 105 %SWITCH ESW(1:7) 106 %OWNINTEGERARRAY STABLE(2:21) = 2, 107 0, 2, 0, 4, 0, 4, 0, 8, 9, 8, 0, 0, 9, 8, 0, 0, 9, 8, 9 108 !STATE TRANSITION TABLE FOR 109 ! REMOVE FUNCTION (AND NIF 110 ! AND ERRORS) 111 %OWNINTEGERARRAY ATABLE(2:21) = 1, 112 5, 7, 7, 1, 6, 7, 7, 2, 2, 1, 3, 3, 1, 7, 4, 4, 7, 4, 4 113 !ACTION TABLE FOR STATE 114 ! TRANSITIONS 115 %OWNINTEGERARRAY ETABLE(2:21) = 2, 116 0, 2, 0, 4, 0, 4, 0, 10, 10, 8, 8, 9, 9, 8, 8, 9, 9, 10, 10 117 !STATE TRANSITION TABLE FOR 118 ! ERROR RECOVERY 119 %OWNINTEGERARRAY DTABLE(2:21) = 192(8), 120 128, 128, 192, 0, 0, 192, 192, 0, 0, 192, 0, 0 121 !DISCONNECT TABLE FOR 122 ! ERROR RECOVERY 123 %OWNINTEGER MLINE, MPROC, FN, FR, SOAD, SOND, SIAD, SIND 124 %OWNINTEGER SOP, SIP, FQ, DISC, STATE, ORIG, NOTORIG, CPN 125 %OWNINTEGER NP, PT, LF 126 %OWNINTEGER I, J, K, L, M, N, N1, TEMP, CBASE, SEQNO 127 %OWNRECORD (DUMMYF)DUMMY 128 %OWNRECORD (CPF) %NAME CP 129 %OWNRECORD (APF) %NAME AP, LAP, SO, SI, LL, PP, ALT 130 %OWNRECORD (LCPF) %NAME LCP, KK, MM, FL 131 %OWNRECORD (LCPXF) %NAME LCPX 132 %OWNRECORD (MPF) %NAME MP 133 %OWNRECORD (MPXF) %NAME MPX 134 %OWNRECORD (LCPF) %ARRAY C(-3:CSIZE) 135 136 137 040016 %ROUTINE STOP(%INTEGER N) 138 %CONSTINTEGERARRAY M(1:9) = 'D', 'I', 'S', 'A', 'S', 'T', 'E', 'R', ' ' 139 %INTEGER I 140 040040 %CYCLE I = 1, 1, 9 141 040060 PRINTSYMBOL(M(I)) 142 040100 %REPEAT 143 ! PRINTSTRING("DISASTER ") 144 040102 PRINTSYMBOL('A'-1+N) 145 040120 NEWLINE 146 040124 %RETURNIF N >= 20 147 040146 *K'104001' 148 040150 %END 149 150 151 040152 %RECORD (MPF) %MAP GETSPACE(%INTEGER S) 152 !GET A SHORT BUFFER 153 %RECORD (PF)P 154 040170 P_SERVICE = BUFFER MANAGER 155 040176 P_REPLY = OWNID 156 040204 P_FN = REQUEST BUFFER 157 040210 P_LEN = 1; !SHORT BUFFER 158 040216 PONOFF(P); !SEND A MESSAGE AND WAIT FOR 159 ! REPLY 160 040232 %RESULT == P_MES 161 %END 162 163 164 040240 %ROUTINE REQUESTSPACE(%INTEGER PROCESS) 165 !GET A LONG BUFFER 166 %RECORD (PF)P 167 040256 P_SERVICE = BUFFER MANAGER 168 040264 P_REPLY = KERNEL SERVICE 169 040272 P_FN = REQUEST BUFFER 170 040276 P_LEN = 0; !LONG BUFFER 171 040302 P_SPARE = PROCESS 172 040310 PON(P) 173 040324 %END 174 175 176 040326 %ROUTINE FREESPACE(%RECORD (MPF) %NAME PP) 177 %RECORD (PF)P 178 040344 P_SERVICE = BUFFER MANAGER 179 040352 P_REPLY = OWNID 180 040360 P_FN = RELEASE BUFFER 181 040366 P_MES == PP 182 040374 PON(P) 183 040410 %END 184 185 186 040412 %ROUTINE MONITOR(%RECORD (PF) %NAME M, %INTEGER LINE, USE) 187 %RECORDFORMAT BF(%BYTEINTEGER USE, LINE, %RECORD (PF) P) 188 %RECORDFORMAT PKF(%BYTEINTEGER FN, SF, %INTEGER ADDR1, %C 189 %BYTEINTEGER NODE1, NODE2, %INTEGER ADDR2, %BYTEINTEGER %C 190 SFLAGS, UFLAGS) 191 %RECORDFORMAT MPF1(%RECORD (MPF) %NAME LINK, %BYTEINTEGER %C 192 LEN, TYPE, %RECORD (PKF)PACKET) 193 %RECORDFORMAT BF1(%BYTEINTEGER USE, LINE, %RECORD (PKF %C 194 )PACKET) 195 %RECORDFORMAT TF(%BYTEINTEGER LINE0, LINE1, %INTEGER %C 196 SEQNO, ERROR, %INTEGERARRAY DATA(1:8)) 197 %RECORDFORMAT MPF2(%RECORD (APF) %NAME PLINK, GLINK, %INTEGER %C 198 LOW, HIGH, NODE, SCORE, LINE, PROC, LIMIT, BUFFS, %BYTEINTEGER %C 199 STATUS, POLL, %RECORD (TF) TRAFFIC) 200 %RECORDFORMAT BF2(%BYTEINTEGER USE, LINE, %RECORD (TF) TRAFFIC) 201 %RECORD (BF) %NAME B, LAST 202 %RECORD (BF1) %NAME B1 203 %RECORD (MPF1) %NAME M1 204 %RECORD (BF2) %NAME B2 205 %RECORD (MPF2) %NAME M2 206 %RECORD (PF)P 207 %INTEGER I 208 040430 %RETURNIF DISPLAY SERVICE = 0 209 040450 LAST == BUFFER(BUFFINDEX) 210 040472 I = BUFFINDEX+1 211 040504 %IF I > BLIMIT %THEN I = 0 212 040520 B == BUFFER(I) 213 040542 %IF B_USE # 0 %THEN BUFFLOST = BUFFLOST+1 %ELSESTART 214 040554 B_LINE = LINE 215 040562 B_USE = USE 216 040566 %IF USE = 1 %THENSTART 217 040576 B_P = M 218 040616 %FINISHELSEIF USE = 2 %THENSTART 219 040630 B1 == B 220 040634 M1 == M 221 040642 B1_PACKET = M1_PACKET 222 040670 %FINISHELSESTART 223 040672 B2 == B 224 040676 M2 == M 225 040704 B2_TRAFFIC = M2_TRAFFIC 226 %FINISH 227 040730 BUFFINDEX = I 228 %FINISH 229 040736 %RETURNIF LAST_USE # 0 230 040742 P_SERVICE = DISPLAY SERVICE 231 040750 P_REPLY = KERNEL SERVICE 232 040756 PON(P) 233 040772 %END 234 235 040774 %RECORD (MPF) %MAP WAIT(%INTEGERNAME LINE, PROC) 236 %RECORDFORMAT PF1 (%BYTEINTEGER SERVICE, REPLY, A1, A2, %C 237 %INTEGERNAME MES, %BYTEINTEGER C1, C2) 238 %RECORDFORMAT BF(%INTEGER I) 239 %RECORD (BF) %ARRAYNAME B 240 %RECORD (PF)P 241 %RECORD (PF1) %NAME P1 242 %RECORD (MPF) %NAME MP 243 041012 L1: P_SERVICE = 0 244 041016 POFF(P) 245 041032 PROC = P_REPLY 246 041046 %IF PROC = BUFFER MANAGER %THENSTART 247 041054 %IF P_SPARE = 0 %THENSTART 248 !BUFFER FOR ROUTING INFO 249 041062 MP == P_MES 250 041070 MP_FN = CLOCKFN 251 041102 %RESULT == MP 252 %FINISH 253 !BUFFER ARRIVED - DO LINE INPUT 254 041114 P_SERVICE = P_SPARE 255 041122 P_REPLY = KERNEL SERVICE 256 041130 P_FN = LINE INPUT 257 041136 PON(P) 258 041152 -> L1 259 %FINISH 260 041154 %IF PROC = CLOCK %THENSTART ; !CLOCK TICK - RETURN DUMMY 261 ! CLOCK BUFFER 262 041160 REQUESTSPACE(0); !ASK FOR BUFFER FOR ROUTING INFO 263 041166 -> L1 264 %FINISH 265 041170 LINE = P_LINE; !SET LINE 266 041204 MP == P_MES 267 041212 %IF P_FN = LINE INPUT %THENSTART 268 !PACKET FROM PROTOCOL HANDLER 269 041222 MP_ADDR1 = SWAB(MP_ADDR1)-MINADDR 270 041252 %UNLESS MP_FN = 4 %OR MP_FN = 5 %THENSTART 271 ! %IF (MP_FN = 1 %OR MP_FN = 7) %AND MP_LEN < 10 %C 272 ! %THENSTART 273 ! MP_ADDR2 = MP_NODE1 << 8+MP_NODE2-MINADDR 274 ! MP_NODE1 = 0 275 ! MP_NODE2 = 0 276 ! MP_SFLAGS = 0 277 ! MP_UFLAGS = 0; !SET UP ATTACH 278 ! %FINISHELSE 279 041272 MP_ADDR2 = SWAB(MP_ADDR2)-MINADDR 280 %FINISH 281 041316 %RESULT == MP 282 %FINISH 283 041322 %IF P_FN >= READ DISPLAY %THENSTART 284 041332 %IF P_FN = INIT DISPLAY %THENSTART 285 041342 DISPLAY SERVICE = PROC 286 041346 B == BUFFER 287 041360 %CYCLE I = 0, 1, (BLIMIT+1)*12-1 288 !CLEAR COMM BUFFER 289 041414 B(I)_I = 0 290 041430 %REPEAT 291 041432 BUFFINDEX = BLIMIT 292 %FINISH 293 041440 P1 == P 294 041452 P1_MES == MYNODE; !ADDRESS OF COMM AREA 295 041470 P1 _ SERVICE = PROC 296 041474 P1_REPLY = KERNEL SERVICE 297 041502 PON(P1) 298 041512 -> L1 299 %FINISH 300 041516 MONITOR(P, PROC, 1); !TELL MONITOR OF NEW LINE STATUS 301 041536 %IF P_LEN = 2 %THEN -> L1; !LHELLO MESSAGE FROM PROT. 302 ! HANDLER 303 041552 %IF P_LEN = 0 %THENSTART ; !LINE UP MESSAGE FROM PROT. 304 ! HANDLER 305 041560 %IF P_SPARE = 0 %OR P_SPARE = 255 %THEN -> L1 306 041602 DUMMY_FN = ATTACHFN; !IF NODE HAS COME UP - SET UP 307 ! DUMMY ATTACH 308 041610 DUMMY_SF = 0 309 041614 DUMMY_ADDR1 = MINADDR 310 041622 DUMMY_NODE1 = P_SPARE 311 041630 DUMMY_NODE2 = P_SPARE 312 041636 DUMMY_ADDR2 = MAXADDR 313 041644 DUMMY_SFLAGS = 0 314 041650 DUMMY_UFLAGS = 0 315 041654 %RESULT == DUMMY 316 %FINISH 317 !FINAL CASE - LINE DOWN 318 ! MESSAGE FROM PROT. HANDLER 319 041666 DUMMY_FN = REMOVEPFN; !SET UP DUMMY REMOVE 320 041674 DUMMY_SF = 0 321 041700 %RESULT == DUMMY 322 %END 323 324 325 041712 %ROUTINE SEND(%RECORD (MPF) %NAME MP, %INTEGER LINE, PROC) 326 %RECORD (PF)P 327 041730 %IF MP == DUMMY %THENSTART 328 041744 %IF MP_SF = 0 %THENRETURN 329 041762 P_FN = BOUNCE LINE; !START LINE NOT SUCCESSFUL 330 041770 P_LINE = LINE 331 041776 %FINISHELSESTART 332 042000 MP_ADDR1 = SWAB(MP_ADDR1+MINADDR) 333 042030 %UNLESS MP_FN = 4 %OR MP_FN = 5 %THENSTART 334 ! %IF (MP_FN = 1 %OR MP_FN = 7) %AND MP_LEN < 10 %C 335 ! %THENSTART 336 ! MP_NODE1 = MP_ADDR2&255 337 ! MP_NODE2 = (MP_ADDR2+MINADDR) >> 8 338 ! %FINISHELSE 339 042050 MP_ADDR2 = SWAB(MP_ADDR2+MINADDR) 340 %FINISH 341 042074 P_FN = LINE OUTPUT 342 042102 P_LINE = LINE 343 042110 P_MES == MP 344 042114 P_LEN = MP_LEN 345 %FINISH 346 042126 P_SERVICE = PROC 347 042134 P_REPLY = KERNEL SERVICE 348 042142 PON(P) 349 042156 %END 350 351 352 042162 %INTEGERFN ROUTESCORE(%INTEGER NODE) 353 %CONSTINTEGERARRAY SCORES(1:15) = 30, 40(2), 10, 20, 10, 80(2), 10, 80(6) 354 042200 %IF NODE <= 15 %THENRESULT = SCORES(NODE) 355 042230 %IF NODE = 80 %THENRESULT = 105 356 042250 %RESULT = 10 357 %END 358 359 360 ! 361 !********************** INITIALISATION *************** 362 ! 363 042260 LINKIN(KERNEL SERVICE) 364 042272 MAP VIRT(BUFFER MANAGER, 4, 3) 365 042314 MAP VIRT(BUFFER MANAGER, 5, 4) 366 042336 MAP VIRT(BUFFER MANAGER, 6, 5) 367 042360 I = SVC(18, 2, 0); !INCREASE PRIORITY 368 ! CHANGE OUT ZERO = T3SERVICE 369 042402 C(0)_LINK == C(0) 370 042414 CADDR == C 371 042426 CBASE = CADDR(0)_LINK; !ADDRESS OF C(0) 372 042436 CLIMIT = CSIZE; !SIZE OF C 373 042444 BUFFADDR == BUFFER 374 042456 PP == NULL; !NEXT NODE TO POLL WITH 375 ! ROUTING INFO. 376 042462 PT = MAXPOLL; !POLL TIMER INTERVAL 377 042470 NP = 0; !NO. OF NODES DIRECTLY ATTACHED 378 042474 BC = 0; !INITIALISE BUFFER COUNT 379 042500 SEQNO = 1; !CONTROL CELL SEQUENCE NO. 380 042506 %CYCLE I = -3, 1, MAXLINE; !INIT FACILITY CHAIN, ATTACH CHAIN 381 !AND LINE POINTERS 382 042542 C(I)_LINK == NULL 383 042556 %REPEAT 384 042560 %CYCLE I = MAXLINE+1, 22, CSIZE-21; !INIT FREE CHAIN AND FREE CELLS 385 042616 C(I)_LINK == C(I+22) 386 042640 %CYCLE J = 1, 1, 21 387 042672 C(I+J)_LINK == NULL 388 042712 %REPEAT 389 042714 %REPEAT 390 042716 C(CSIZE-21)_LINK == NULL 391 042722 FL == C(MAXLINE+1); !INIT FREE CHAIN 392 042734 ALARM(PT) 393 042746 -> NEXT; !WAIT FOR FIRST CUSTOMER 394 ! 395 !*********************** START OF MAIN PROGRAM ***************** 396 ! 397 042750 DATA: MP_ADDR1 = SIAD 398 042762 %IF MPX == NULL %THEN MP_ADDR2 = MP_ADDR1 399 042776 CALL: MLINE = SI_LINE 400 043010 MPROC = SI_PROC 401 043016 %IF MPX == NULL %THENSTART ; !UNLESS SHORT FORM 402 043024 %IF SOND = 0 %THEN SOND = MYNODE 403 043040 %IF SIND = 0 %THEN SIND = MYNODE 404 043054 %IF FR = 0 %THEN MP_NODE1 = SOND %AND MP_NODE2 = SIND %ELSE %C 405 MP_NODE1 = SIND %AND MP_NODE2 = SOND 406 !SET SOURCE AND SINK NODES 407 %FINISH 408 043124 %IF ALT == NULL %THEN -> DUMP %ELSE -> RETRY 409 043134 DELETE:FREESPACE(MP) 410 043144 -> NEXT 411 043146 SUCCEED:MP_SF = 0 412 043156 REPLY:MP_FN = MP_FN!128 413 043170 DUMP: SEND(MP, MLINE, MPROC) 414 043210 NEXT: MP == WAIT(MLINE, MPROC) 415 043234 ALT == NULL 416 043240 RETRY:MPX == NULL 417 043244 AP == NULL 418 043250 CP == NULL 419 043254 FN = MP_FN&127 420 043274 FR = MP_FN-FN 421 043312 %IF FN <= 10 %THEN -> COM(FN); !TIMER TO BE PASSED AS FN 10 422 ! 423 !*************** ERROR CODE ********************* 424 ! 425 COM(0):COM(9): 426 043330 ERR1: FQ = 1; -> FAIL 427 043340 ERR2: FQ = 2; -> FAIL 428 043350 ERR3: FQ = 3; -> FAIL 429 043360 ERR4: FQ = 4; -> FAIL 430 043370 ERR5: FQ = 5; -> FAIL 431 043400 ERR6: FQ = 6; -> FAIL 432 043410 ERR7: FQ = 7 433 043416 FAIL: ERRORS = ERRORS+1 434 043422 DISC = 0 435 043426 %IF FN >= 2 %AND FN <= 6 %AND (FN >= 4 %OR FR # 0) %THENSTART 436 !CLOSE CONNECTION IF ERROR 437 ! WHILE CONNECTED 438 043464 %UNLESS AP == NULL %OR CP == NULL %THENSTART 439 043500 %IF STATE <= 0 %OR STATE > 10 %THEN STOP(1) 440 043524 N = STATE << 1+ORIG 441 043542 -> ESW(ATABLE(N)) 442 043562 ESW(1): %UNLESS SIP # 0 %THENSTART 443 043570 ESW(2):ESW(3): ISSUE(6, 136); !ISSUE NIF WITH DISCONNECT TO 444 ! REMOTE END 445 %FINISH 446 043604 -> EL1 447 043606 ESW(5): ISSUE(130, 135); -> EL1; !ISSUE MF7 448 043624 ESW(6): ISSUE(131, 135); !ISSUE CF7 449 ESW(4):ESW(7):EL1: 450 043640 DISC = DTABLE(N); !SET DISCONNECT BITS 451 043656 %IF (%NOT MPX == NULL) %AND MPX_SFLAGS < 128 %AND %C 452 DISC <= 128 %THEN CP_STATE = ETABLE(N) %ELSE %C 453 CP_ERROR = FQ %AND CCBFREE(STABLE(N)) 454 !GO TO NEW STATE 455 043742 %FINISHELSESTART ; !ERROR DISCONNECT - NO CONNECTION 456 043744 %IF FN = 6 %OR FQ = 2 %THEN DISC = 64 %ELSE DISC = 192 457 !DONT SET DISC IN REPLY TO NIF 458 !OR IF SENDER NOT ATTACHED 459 %FINISH 460 044002 -> NIF 461 %FINISH 462 044004 %IF FR # 0 %THENSTART 463 !ISSUE IF TO RESPONSE, 464 ! SENDBLOCK, STATUS, OR NIF 465 044012 NIF: MP_FN = 6 466 044024 %UNLESS MPX == NULL %THENSTART 467 !CONVERT TO LONG FORM 468 044032 MP_UFLAGS = MPX_UFLAGS 469 044040 MP_SFLAGS = MPX_SFLAGS 470 044046 MP_ADDR2 = MPX_ADDR 471 044054 MP_NODE2 = MYNODE 472 044062 MP_NODE1 = MYNODE; !OTHER FIELDS POSITIONED OK 473 %FINISH 474 044070 MP_LEN = 10; !DELETE DATA 475 044076 %IF FR = 0 %THENSTART ; !EXCHANGE ADDRESSES FOR 476 ! FAULTY FUNCTION 477 !AS OPPOSED TO RESPONSE 478 044104 TEMP = MP_ADDR2 479 044112 MP_ADDR2 = MP_ADDR1 480 044120 MP_ADDR1 = TEMP 481 044126 TEMP = MP_NODE2 482 044142 MP_NODE2 = MP_NODE1 483 044150 MP_NODE1 = TEMP 484 %FINISH 485 044154 MP_SFLAGS = MP_SFLAGS&63+DISC 486 044174 MP_UFLAGS = FN+FR; !SET FAILING FUNCTION IN 487 ! FLAGS WORD 488 044206 MP_SF = FQ+128; !AND FAIL QUAL IN FQ WORD 489 044222 MONITOR(MP, MLINE, 2); !NIF ISSUED 490 044240 -> DUMP 491 %FINISHELSESTART ; !ISSUE RESPONSE IN OTHER CASES 492 044244 MP_LEN = 10; !DELETE DATA 493 044256 MP_SF = FQ+128 494 044272 -> REPLY 495 %FINISH 496 ! 497 !************* ATTACH ******************* 498 ! 499 COM(1): !ATTACH 500 044276 %IF FR # 0 %THEN -> ERR1; !RESPONSE?? 501 044310 %IF MP_NODE1 # MP_NODE2 %THEN -> ERR1 502 !ONE NODE ONLY 503 044330 %IF MP_ADDR2 < MP_ADDR1 %THEN -> ERR1 504 !RANGE INSIDE OUT 505 044344 %IF MP_SFLAGS <= 0 %OR MP_SFLAGS > AL %THEN MP_SFLAGS = AL 506 !CHECK ATTACH LIMIT 507 044376 %IF MP_NODE1 # 0 %THENSTART 508 044404 ACBGET(0) 509 044412 %UNLESS AP == NULL %THEN -> ERR2; !ALREADY ATTACHED ON THIS LINE 510 044424 ACBGET(1); !FIND POSITION IN LIST 511 044434 %FINISHELSESTART 512 044436 ACBGET(1); !LOOK UP HIGH ADDRESS 513 044446 %IF %NOT AP == NULL %OR (%NOT LAP == C(-2) %C 514 %AND LAP_NODE = SOND %AND LAP_HIGH >= SOAD) %THEN -> ERR2 515 !IF ALREADY ATTACHED IN PART 516 044520 %IF SOAD >= TERM255 %THEN -> ERR2 517 !TERMINAL 255 RESERVED 518 %FINISH 519 044534 ACBASSIGN(MLINE); !ASSIGN ACB IN STATE 0 (ATTACHED) 520 044544 %IF AP == NULL %THEN -> ERR3; !OUT OF SPACE 521 044556 AP_LOW = SOAD 522 044564 AP_HIGH = SIAD; !SET LOW AND HIGH ADDRESSES 523 044572 AP_NODE = SOND; !SET NODE 524 044600 %IF SOND # 0 %THEN AP_SCORE = ROUTESCORE(SOND) 525 044624 AP_LINE = MLINE 526 044632 %UNLESS SOAD = MINADDR %AND SIAD = MAXADDR %THEN %C 527 AP_STATUS = 1 528 !SET TERMINAL MARKER 529 !CLEAR POLL FLAG 530 044660 AP_PROC = MPROC; !SET PROCESS 531 044666 AP_LIMIT = AL; !SET ATTACH LIMIT 532 044674 AP_NT = SOAD&X'FF00'+SOND; !FOR MONITORING 533 044712 MONITOR(AP, MLINE, 3); !TELL MONITOR OF ATTACH 534 044730 -> SUCCEED 535 ! 536 !************** SENDMESSAGE AND CONNECT ********************** 537 ! 538 COM(2):COM(3): !SENDMESSAGE, CONNECT 539 044734 ACBGET(0) 540 044742 %IF AP == NULL %THEN -> ERR2; !SOURCE NOT ATTACHED OR REMOVING 541 044754 %IF SIAD = ROUTEADDR %THENSTART 542 !ROUTING INFORMATION PACKET 543 044770 %IF SO_STATUS # 0 %THEN -> QUOTE 544 045006 L = SCORE(SO)-LF; !LINK SCORE 545 045024 LAP == C(-2); !OUR ACB POINTER 546 045036 I = 2; J = MP_LEN-14; !NODE LIST PASSED, 2 SPARE 547 ! SLOTS FOR TIMING ETC. 548 045070 %IF J < 0 %THEN -> QUOTE 549 ! %IF J >= 0 %THENSTART 550 !NODE PROCESS AND NOT NULL 551 045076 N1 = 0 552 %CYCLE 553 !CYCLE THROUGH NEW QUOTE 554 045102 AP == LAP_GLINK 555 045114 %UNLESS AP == NULL %THEN K = AP_NODE %ELSE K = 256 556 !OUR NODE 557 045140 %UNLESS K = 0 %THENSTART ; !SKIP TERMINAL ENTRIES 558 045152 %IF I <= J %THENSTART 559 !SET NODE AND SCORE 560 045162 N = MP_DATA(I+2) 561 045206 M = MP_DATA(I+3) 562 045232 %IF M <= 250 %THENSTART 563 045240 M = M+L 564 045246 %IF M >= 250 %THEN M = 250 565 %FINISH 566 045264 %FINISHELSE M = 255 %AND N = 256 567 045302 %IF N > 255 %AND K > 255 %THENEXIT 568 !LIST COMPLETELY PROCESSED 569 045322 %IF N > K %THENSTART 570 !OUR NODE NOT KNOWN TO HIM 571 045332 %IF AP_CPTR_LINK == SO %THEN ACBFREE(AP) %AND AP %C 572 == NULL 573 !IF ROUTE VIA HIM 574 !DELETE NODE 575 !TRY NEXT NODE IN OUR LIST 576 ! WITHOUT STEPPING ON THROUGH 577 ! QUOTE 578 !STEP ON THROUGH OUR NODES 579 045360 %FINISHELSESTART 580 045362 %IF N <= N1 %THENEXIT 581 !CHECK LIST IN ASCENDING ORDER 582 045372 %UNLESS M >= 255 %OR N = MYNODE %THENSTART 583 !MAX SCORE MEANS NO ROUTE 584 !CHECK OUR NODE NOT GIVEN 585 !CHECK ZERO SCORE NOT GIVEN 586 045412 %IF N = K %THENSTART 587 !UPDATE EXISTING NODE 588 045422 %IF AP_PROC = 0 %AND (M < AP_SCORE %OR %C 589 AP_CPTR_LINK == SO) %THENSTART 590 !SAME ROUTE OR LOWER SCORE, 591 ! NOT DIRECTLY ATTACHED 592 045454 AP_SCORE = M 593 !NEW SCORE 594 045462 AP_CPTR_LINK == SO 595 !NEW ROUTE 596 %FINISH 597 045470 %FINISHELSESTART 598 !NEW NODE NOT KNOWN TO US 599 045472 ACBASSIGN(-2); !ADD TO OUR TABLES 600 045502 %UNLESS AP == NULL %THENSTART 601 !IF NO SPACE? NOT REACHABLE 602 ! MEANTIME, SHOULD BE PICKED 603 ! UP ON NEXT TICK 604 045510 AP_LOW = MINADDR 605 045516 AP_HIGH = MAXADDR 606 !LOW AND HIGH ADDRESS, REDUNDANT 607 045524 AP_NODE = N 608 045532 AP_SCORE = M 609 !NODE + SCORE 610 !PROCESS ZERO INDICATES 611 ! INDIRECT ATTACHMENT 612 045540 AP_CPTR_LINK == SO 613 !ROUTE 614 %FINISH 615 %FINISH 616 045546 %FINISHELSE AP == NULL 617 045554 I = I+2 %AND N1 = N %IF AP == NULL %OR AP_PROC = 0;!STEP ON THROUGH QUOTE 618 %FINISH 619 %FINISH 620 045604 %UNLESS AP == NULL %THEN LAP == AP 621 045616 %REPEAT 622 ! %FINISH 623 045622 QUOTE: %IF FR # 0 %THEN SO_POLL = 0 %AND -> DELETE 624 045644 SETUPQUOTE(SO, MP, 1) 625 045664 -> SUCCEED; !ISSUE REPLY, EXCHANGE INFO 626 %FINISH 627 045670 %IF FR = 0 %THENSTART ; !FUNCTION 628 045702 ACBGET(-1); !FIND SINK 629 045712 %IF AP == NULL %THEN -> ERR5 630 !SINK NOT KNOWN 631 045724 %IF AP_SCORE > THRESHOLD %THEN -> ERR4 632 !WEIGHT EXCEEDS THRESHOLD 633 045740 CCBGET(0); !LOOK UP SOURCE PORT 634 045746 %IF CP == NULL %THEN CCBGET(1);!LOOK UP FACILITY 635 045764 %UNLESS CP == NULL %THEN -> ERR3 636 !PORT BUSY 637 045776 MP_SF = 0; !ENSURE NOONE TRANSMITS INFO HERE 638 046006 %IF FN = 2 %THEN K = 0 %ELSESTART 639 !GET BUFFER COUNTS 640 046024 K = MP_SFLAGS >> 1&63 641 046050 %IF K = 0 %THEN K = 8 %AND MP_SFLAGS = MP_SFLAGS+16 642 !MINIMUM OF ONE FORWARD BUFFER 643 %FINISH 644 046100 I = K >> 3; !ORIGINATORS BUFFERS 645 046120 J = K&7; !RESPONDERS BUFFERS 646 046134 %IF FN = 2 %THENSTART 647 046144 %IF SO_BUFFS = 255 %OR SI_BUFFS = 255 %THEN -> ERR6 648 046200 CCBASSIGN(1); !ASSIGN CCB IN STATE 1 (SENDING) 649 046210 %FINISHELSESTART 650 046212 %IF SO_BUFFS >= SO_LIMIT %OR SI_BUFFS >= SI_LIMIT %THEN -> ERR6 651 046246 %IF BC >= BL %THEN -> ERR6 652 046262 CCBASSIGN(3); !ASSIGN CCB IN STATE 3 (CONNECTING) 653 %FINISH 654 046272 %IF CP == NULL %THEN -> ERR6; !IF NO CCB AVAILABLE 655 046304 CP_LIM(0) = I 656 046312 CP_LIM(1) = J; !SET BUFFER MAXIMA 657 046320 CP_NT(0) = SOAD&X'FF00'+SOND 658 046336 CP_NT(1) = SIAD&X'FF00'+SIND; !RECORD ORIGINAL ADDRESSES FOR 659 !MONITORING 660 046354 CP_LINE(0) = SO_LINE 661 046366 CP_LINE(1) = SI_LINE 662 046400 BC = BC+I+J+1; !ASSIGN BUFFERS 663 046422 SO_BUFFS = SO_BUFFS+I+1; !ASSIGN SOURCE BUFFERS 664 046440 SI_BUFFS = SI_BUFFS+J+1; !ASSIGN SINK BUFFERS 665 !COUNT ONE FOR EACH CONNECT 666 046456 %FINISHELSESTART ; !RESPONSE 667 046462 %IF SOP # 0 %AND MP_SF >= 128 %AND MP_SF < 128+8 %THEN -> ERR1 668 !ILLEGAL TO ISSUE NETWORK 669 ! LEVEL FAILURE UNLESS NODE 670 046520 CCBGET(1); !LOOK UP SOURCE FACILITY 671 046530 %IF CP == NULL %THEN -> ERR7; !NO CB FOR RESPONSE 672 046542 TEMP = CP_ADDR(1); !NOTE ORIGINATORS RESPONDING 673 ! ADDRESS 674 046550 %UNLESS STATE = FN %OR STATE = FN*3-5 %THEN -> ERR7 675 !REPLY NOT EXPECTED 676 046606 N = FN*3+SOP+SIP 677 046632 %IF FN = 2 %OR MP_SF >= 128 %THENSTART 678 !MESSAGE OR FAILED CONNECT 679 046656 COUNTS(N-3) = COUNTS(N-3)+1 680 046664 %IF FN = 2 %THENSTART 681 046674 SI_MESSOUT = SI_MESSOUT+1; !ORIG SENT A MESSAGE 682 046704 SO_MESSIN = SO_MESSIN+1; !RESP RECEIVED A MESSAGE 683 046714 %FINISHELSESTART 684 046716 SI_CFOUT = SI_CFOUT+1; !ORIG SENT A CONNECT & IT FAILED 685 046726 SO_CFIN = SO_CFIN+1; !RESP REJECTED A CONNECT 686 %FINISH 687 046736 CCBFREE(0) 688 046744 %UNLESS STATE = 1 %OR STATE = 3 %THEN -> DELETE 689 !DELETE RESPONSE IF REMOVING 690 046770 %IF MP_SF >= 128 %ANDNOT SO_GLINK == NULL %AND %C 691 SOND # 0 %AND SO_GLINK_NODE = SOND %THENSTART 692 047032 MP_FN = FN; MP_SF = 0; ALT == SO 693 %FINISH 694 047050 %FINISHELSESTART ; !SUCCESSFUL CONNECT 695 047054 K = MP_SFLAGS >> 1&63 696 047100 %IF K = 0 %THEN K = 8 697 047110 I = CP_LIM(0)-K >> 3 698 047142 J = CP_LIM(1)-K&7 699 !CHANGE IN BUFFER ALLOC IN I,J 700 047170 %IF I < 0 %OR J < 0 %THEN -> ERR1 701 !ILLEGAL ATTEMPT TO INCREASE 702 ! BUFFER ALLOC 703 047204 KK == CP; LL == LCP 704 !SAVE CCB VARIABLES 705 047216 CCBGET(-1); !LOOK UP SOURCE PORT 706 047226 MM == CP; !SAVE POINTER 707 047234 CP == KK; LCP == LL 708 !RESTORE CCB VARIABLES 709 047250 %UNLESS MM == NULL %THEN -> ERR3 710 !IF SOURCE PORT ALREADY IN USE 711 047262 COUNTS(N) = COUNTS(N)+1 712 047274 SI_COKOUT = SI_COKOUT+1; !ORIG SENT A CONNECT AND IT SUCCEEDED 713 047304 SO_COKIN = SO_COKIN+1; !RESP ACCEPTED A CONNECT 714 047314 CP_LIM(0) = CP_LIM(0)-I 715 047340 CP_LIM(1) = CP_LIM(1)-J 716 !ADJUST MAXIMA 717 047360 BC = BC-I-J; !RETURN GLOBAL BUFFERS 718 047400 SO_BUFFS = SO_BUFFS-J; !RETURN BUFFERS TO SOURCE 719 047412 SI_BUFFS = SI_BUFFS-I; !RETURN BUFFERS TO SINK 720 047424 CP_ADDR(1) = MP_ADDR2; !SET TRUE RESPONDING ADDRESS 721 047442 LCP_LINK == CP_LINK(1)_LINK 722 !UNHOOK FROM FACILITY CHAIN 723 047452 CP_LINK(1)_LINK == SO_CPTR_LINK 724 047464 SO_CPTR_LINK == CP_LINK(1) 725 !ADD TO RESPONDERS CHAIN 726 047474 %IF STATE = 4 %THENSTART 727 !IF REMOVING 728 047504 CP_STATE = 8; !GO TO CONNECTED SOURCE REMOVING 729 047516 FQ = 8 730 047524 DISC = 128 731 047532 -> NIF; !ISSUE NIF WITH DISCONNECT 732 047536 %FINISHELSE CP_STATE = 5 733 !SET STATE 5 (CONNECTED) 734 047550 %UNLESS SIP # 0 %THENSTART 735 047556 TEMP = TERM255+CPN // 22 736 047600 %IF MYNODE > SI_NODE %THEN TEMP = TEMP!!255 737 047624 CP_ADDR(0) = TEMP; !ALLOCATE A KERNEL PORT 738 ! NUMBER FOR INTER NODE 739 ! CONNECTION 740 !USE THE CCB NO. AS THE PORT 741 ! NO. THIS GUARANTEES UNIQUENESS 742 %FINISH 743 047636 MONITOR(CP, 0, 5); !CONNECT ACCEPTED 744 %FINISH 745 047654 MP_ADDR2 = TEMP; !RESET RESPONDING ADDRESS 746 %FINISH 747 047666 -> CALL 748 ! 749 !************ SENDBLOCK AND STATUS ******************** 750 ! 751 COM(4):COM(5): !SENDBLOCK, STATUS 752 047672 MPX == MP; !SHORT FORM 753 047700 ACBGET(0) 754 047706 %IF AP == NULL %THEN -> ERR2; !SOURCE NOT ATTACHED OR REMOVING 755 047720 CCBGET(0); !LOOK UP PORT 756 047726 %IF CP == NULL %OR STATE < 5 %THEN -> ERR6 757 !PORT NOT CONNECTED 758 047750 %IF SOP # 0 %THENSTART 759 047756 %IF MPX_SFLAGS >= 128 %AND FR # 0 %AND STATE = 5 %THEN -> ERR1 760 !ILLEGAL TO INITIATE 761 ! DISCONNECT WITH REPLY 762 050014 MPX_SF = 0; !ENSURE NOONE TRANSMITS INFO HERE 763 %FINISH 764 050020 %IF STATE < 8 %THENSTART ; !IF NOT REMOVING 765 !NOW DO FLOW CONTROL 766 050034 %IF FN = 4 %THENSTART ; !SENDBLOCK 767 050044 M = MPX_SFLAGS >> 4&7; !RESPONSE COUNT 768 050074 %IF FR = 0 %THENSTART ; !SENDBLOCK FUNCTION 769 050102 %IF CP_CNTL(ORIG) >= CP_LIM(ORIG) %THEN -> ERR3 770 !PORT BUSY - ALL BUFFERS USED 771 050136 CP_CNTL(ORIG) = CP_CNTL(ORIG)+1 772 !ONE BLOCK RECEIVED 773 050174 %FINISHELSESTART ; !SENDBLOCK RESPONSE 774 050176 %IF M = 0 %THEN M = 1; !MINIMUM OF ONE RESPONSE 775 %FINISH 776 050210 %IF M > CP_CNTL(NOTORIG) %THEN -> ERR7; !INVALID RESPONSE COUNT 777 050242 CP_CNTL(NOTORIG) = CP_CNTL(NOTORIG)-M 778 !M RESPONSES RECEIVED 779 050302 %FINISHELSESTART ; !STATUS 780 050304 %IF FR = 0 %THENSTART 781 050312 %IF CP_STA(ORIG) # 0 %THEN -> ERR3 782 !PORT BUSY 783 050332 CP_STA(ORIG) = 1 784 050346 %FINISHELSESTART 785 050350 %IF CP_STA(NOTORIG) = 0 %THEN -> ERR7 786 !RESPONSE NOT EXPECTED 787 050370 CP_STA(NOTORIG) = 0 788 %FINISH 789 %FINISH 790 050402 N = FN*3+SOP+SIP 791 050426 COUNTS(N) = COUNTS(N)+1 792 050434 %IF FR = 0 %THENSTART 793 !COUNT BLOCKS AND BYTES SENT 794 !COUNT BYTES IN GROUPS OF 16 795 050442 CP_BLOCKS(ORIG) = CP_BLOCKS(ORIG)+1 796 050500 CP_BYTES(ORIG) = CP_BYTES(ORIG)+(MP_LEN+7) >> 4 797 050564 SO_BLKOUT = SO_BLKOUT+1; !ORIG SENT A BLOCK 798 050574 SI_BLKIN = SI_BLKIN+1; !RESP RECEIVED A BLOCK 799 050604 %FINISHELSESTART 800 !COUNT REPLIES RECEIVED 801 050606 CP_REPLIES(NOTORIG) = CP_REPLIES(NOTORIG)+1 802 %FINISH 803 050644 %IF MPX_SFLAGS >= 128 %THENSTART 804 !IF DISCONNECT 805 050660 %IF STATE = 5 %THEN CP_ERROR = 32 %AND %C 806 CP_STATE = 6+ORIG %ELSESTART 807 !IF NORMAL STATE 808 !GOTO DISCONNECTING STATE 809 !STATE 6 - ORIGINATOR 810 ! DISCONNECTING 811 !STATE 7 - RESPONDER 812 ! DISCONNECTING 813 050720 %IF STATE # 7-ORIG %THEN -> ERR6 814 !DISCONNECT ALREADY ISSUED 815 050742 CCBFREE(0); !COMPLETE DISCONNECT SEQUENCE 816 %FINISH 817 %FINISH 818 050750 -> DATA 819 %FINISHELSESTART ; !IF REMOVING 820 050754 %UNLESS STATE = 10 %OR STATE = 9-ORIG %THEN STOP(3) 821 !FN FROM REMOVING TERMINAL 822 ! SHOULD ALREADY BE PICKED UP 823 051012 %IF MPX_SFLAGS >= 128 %THENSTART 824 !ACKNOWLEDGEMENT FROM OTHER END 825 051026 %IF STATE = 10 %THEN CCBFREE(8+ORIG) %ELSE CCBFREE(0) 826 %FINISH 827 051064 -> DELETE; !DISCARD MESSAGE 828 %FINISH 829 ! 830 !************ NETWORK INFORMATION FUNCTION ************** 831 ! 832 COM(6): !NIF 833 051070 NIFS = NIFS+1 834 051074 ACBGET(0) 835 051102 %IF AP == NULL %THEN -> ERR2; !SOURCE NOT ATTAHED OR REMOVING 836 051114 %IF MP_SFLAGS >= 128 %THENSTART 837 !NIF WITH DISCONNECT 838 051134 CCBGET(0); !LOCATE CCB BY PORT 839 051142 %IF CP == NULL %THENSTART 840 051150 %IF SOP # 0 %THEN -> ERR6; !ERROR IF USER NIF - NOT 841 ! CONNECTED 842 051162 CCBGET(1); !TRY TO LOCATE BY FACILITY 843 051172 %IF CP == NULL %THEN -> DELETE 844 !NO CCB - CROSS WITH MR, CR ETC. 845 %FINISH 846 051204 %IF SOP # 0 %THENSTART ; !IF USER NIF 847 051212 %UNLESS (STATE = 10 %OR STATE = 9-ORIG) %AND FR # 0 %C 848 %THEN -> ERR1 849 !ERROR IF NOT CORRECT STATE 850 !OR ATTEMPT TO ISSUE NIF - 851 ! INVALID 852 051252 CCBFREE(0); !DISCONNECT CCB 853 051260 -> DELETE 854 !DISCARD MESSAGE IF LOCAL 855 %FINISH 856 051264 %IF STATE <= 0 %OR STATE > 10 %THEN STOP(4) 857 !?? 858 051310 %IF FR = 0 %THENSTART ; !FUNCTION 859 !NETWORK DISCONNECT FROM 860 ! CONNECT ORIGINATOR OR RESPONDER 861 051316 N = STABLE(STATE << 1+ORIG) 862 051342 -> NSW(ATABLE(STATE << 1+ORIG)) 863 !ACTION 864 051374 NSW(1): %IF SIP = 0 %THENSTART 865 051402 NSW(2): ISSUE(6, 136); !ISSUE NIF WITH DISCONNECT 866 %FINISH 867 051416 CP_ERROR = MP_SF+16 868 051446 CCBFREE(N) 869 051456 -> SUCCEED 870 051462 NSW(3): CCBFREE(N) 871 051472 -> DATA 872 051476 NSW(4):NL1: CCBFREE(N) 873 051506 -> DELETE 874 NSW(5):NSW(6):NSW(7): !INVALID ACTIONS 875 051512 %FINISHELSESTART ; !RESPONSE 876 051514 %IF STATE = 10 %THEN CCBFREE(8+ORIG) %AND -> DELETE 877 051546 %IF STATE = 9-ORIG %OR (ORIG # 0 %AND (STATE = 2 %OR %C 878 STATE = 4)) %THENSTART 879 !RESPONSE TO DISCONNECT FROM 880 ! CONNECT 881 !ORIGINATOR OR RESPONDER AS 882 ! APPROPRIATE 883 !OR 884 !RESPONSE TO DISCONNECT FROM 885 ! CONNECT ORIGINATOR WHILE 886 ! CONNECTION BEING SET UP 887 051612 CCBFREE(0) 888 051620 -> DELETE 889 %FINISH 890 %FINISH 891 051624 %FINISHELSESTART ; !NIF WITHOUT DISCONNECT 892 051626 %IF SOP = 0 %AND MP_UFLAGS = 6 %THEN -> DELETE 893 !IGNORE REPLY TO OUR NIF FROM 894 ! REMOTE KERN 895 %FINISH 896 051654 CP == NULL; !FOR BENEFIT OF ERROR CLOSE CODE 897 051660 -> ERR1; !ANYTHING ELSE INVALID 898 ! 899 !****************** REMOVE *********************** 900 ! 901 COM(7): !REMOVE ADDRESS 902 COM(8): !REMOVE PROCESS 903 051664 %IF FR # 0 %THEN -> ERR1; !RESPONSE?? 904 051676 LAP == C(-2); !SET PREVIOUS ACB FRO CHAIN SCAN 905 051710 I = 0; !SET COUNT FO ACBS REMOVED 906 %CYCLE 907 051714 AP == LAP_GLINK 908 051726 %IF AP == NULL %THENEXIT ; !END OF ACB CHAIN 909 051734 %IF AP_PROC # 0 %THEN L = AP_LINE %ELSE LL == AP_CPTR_LINK %C 910 %AND L = LL_LINE 911 !GET PROCESS 912 051776 %UNLESS L = MLINE %THEN -> R1 913 !CONTINUE UNLESS MATCH OF PROCESS 914 052012 %IF FN = 7 %THENSTART 915 052022 L = MP_NODE1 916 052042 %IF L = MYNODE %THEN L = 0 917 !GET NODE 918 052054 %UNLESS AP_LOW = MP_ADDR1 %AND AP_HIGH = MP_ADDR2 %AND %C 919 AP_NODE = L %THEN -> R1 920 !CONTINUE UNLESS MATCH OF 921 ! ADDRESS AND NODE 922 %FINISH 923 052110 LCP == C(-3); !HEAD OF FACILITY CHAIN 924 052122 %CYCLE K =- 1, 1, 0; !COULD OPTIMISE THIS IN COMPILER 925 %CYCLE 926 052160 LCPX == LCP 927 052166 CP == LCP_LINK 928 052176 %IF CP == NULL %THENEXIT 929 !IF END OF CHAIN 930 052200 %UNLESS CP_PTR(0)_LINK == AP %THEN LCP == CP %ELSESTART 931 !STEP ON IF FOR DIFFERENT 932 ! NODE (FACILITY CHAIN ONLY) 933 052222 CPN = (LCPX_LINK-CBASE) >> 1 934 052244 ORIG = CPN&1 935 052254 NOTORIG = 1-ORIG 936 !ORIG 0 IF ORIGINATOR - 1 IF 937 ! RESPONDER 938 052266 CP == C(CPN-ORIG) 939 052310 STATE = CP_STATE 940 052316 %IF STATE <= 0 %OR STATE > 10 %THEN STOP(5) 941 !EH?? 942 052340 %UNLESS CP_PTR(0)_LINK == CP_PTR(1)_LINK %THENSTART 943 !NO ACTION FOR CONNECTION TO SELF 944 052354 -> RSW(ATABLE(STATE << 1+ORIG)) 945 !ACTION 946 052406 RSW(1): LL == CP_PTR(NOTORIG)_LINK 947 052426 %UNLESS LL_LINE >= 128 %THENSTART 948 !UNLESS SINK LOCAL 949 052442 RSW(2):RSW(3): ISSUE(6, 136) 950 !ISSUE NIF WITH DISCONNECT 951 %FINISH 952 052456 -> R2 953 052460 RSW(5): ISSUE(130, 135); -> R2 954 !ISSUE MF7 955 052476 RSW(6): ISSUE(131, 135) 956 !ISSUE CF7 957 %FINISH 958 052512 RSW(4):RSW(7):R2: %IF CP_ERROR = 0 %THEN CP_ERROR = 8 959 052532 CCBFREE(STABLE(STATE << 1+ORIG)) 960 !GO TO NEW STATE 961 %FINISH 962 052560 %REPEAT 963 052564 %IF AP_PROC = 0 %THEN -> R4 964 052576 LCP == AP_CPTR; !HEAD OF FACILITY CHAIN 965 052606 %REPEAT 966 052612 MONITOR(AP, AP_LINE, 4); !TELL MONITOR OF REMOVE 967 052636 R4: ACBFREE(AP); !DELETE ACB 968 052646 I = I+1; !COUNT AND CONTINUE REMOVING ACBS 969 052652 -> R3 970 052654 R1: LAP == AP; !STEP ON THROUGH ACBS 971 052662 R3: %REPEAT 972 052666 MP_SF = I 973 052700 %IF I = 0 %AND FN = 7 %THEN -> ERR2 974 !ERROR - NOT ATTACHED IF 975 ! REMOVE ADDRESS 976 052722 -> REPLY 977 ! 978 !****************** TIMER TICK ************************ 979 ! 980 COM(10): 981 052726 LL == PP 982 %CYCLE 983 052734 %IF PP == NULL %THENSTART 984 052742 %IF NP > 0 %THENSTART ; FUDGE1:PT=MAXPOLL//NP;FUDGE2: %C 985 052766 %FINISHELSE PT = MAXPOLL 986 !RESET POLL INTERVAL 987 052776 NP = 0; PP == C(-1)_LINK 988 053010 %FINISHELSESTART 989 053012 %IF PP_STATUS = 0 %AND PP_PROC # 0 %AND PP_POLL = 0 %C 990 %THENSTART 991 !IF DIRECTLY CONNECTED SWITCH 992 053034 SETUPQUOTE(PP, MP, 0) 993 053050 SEND(MP, PP_LINE, PP_PROC) 994 053074 PP_POLL = 1; !MARK ROUTING PACKET SENT 995 053106 NP = NP+1; PP == PP_GLINK 996 053120 %EXIT 997 %FINISH 998 053122 PP == PP_GLINK 999 %FINISH 1000 053130 %IF PP == LL %THEN FREESPACE(MP) %ANDEXIT 1001 053152 %REPEAT ; !FIND NEXT NODE TO POLL 1002 053154 ALARM(PT); !SET POLL INTERVAL, CYCLE 1003 ! ROUND ALL NODES IN 10 SECONDS 1004 053166 -> NEXT 1005 ! 1006 !*************** SUBROUTINES ********************** 1007 ! 1008 1009 1010 053172 %ROUTINE ACBGET(%INTEGER FLG) 1011 !LOOK UP ACB ON ATTACH CHAIN 1012 !FLG=0 - LOOK FOR MATCH OF 1013 ! SOURCE ADDRESS 1014 !FLG=1 - LOOK FOR MATCH OF 1015 ! SINK ADDRESS 1016 %INTEGER J 1017 %RECORD (APF) %NAME LAP1, BEST, HEAD 1018 053214 %IF FLG >= 0 %THENSTART 1019 053222 %UNLESS MPX == NULL %THENSTART 1020 !IF SENDBLOCK 1021 053230 SOAD = MPX_ADDR 1022 053236 SOND = 0 1023 053242 %FINISHELSESTART 1024 053244 %IF FR = 0 %THENSTART ; !IF SOURCE AND FUNCTION OR 1025 ! SINK AND RESPONSE 1026 053252 SOAD = MP_ADDR1 1027 053264 SIAD = MP_ADDR2 1028 053272 SOND = MP_NODE1 1029 053306 SIND = MP_NODE2; !TAKE ADDR1 AS SOURCE 1030 053322 %FINISHELSESTART ; !IF SINK AND FUNCTION OR 1031 ! SOURCE AND RESPONSE 1032 053324 SOAD = MP_ADDR2 1033 053336 SIAD = MP_ADDR1 1034 053344 SOND = MP_NODE2 1035 053360 SIND = MP_NODE1; !TAKE ADDR2 AS SOURCE 1036 %FINISH 1037 053374 %IF SIND = MYNODE %THEN SIND = 0 1038 053406 %IF SOND = MYNODE %THEN SOND = 0 1039 !SET SINK AND SOURCE NODES 1040 %FINISH 1041 %FINISH 1042 053420 %IF FLG = 0 %THENSTART ; !FIND BY PROCESS 1043 053426 AP == C(MLINE) 1044 %CYCLE 1045 053446 LAP == AP 1046 053454 AP == AP_PLINK; !STEP ON DOWN CHAIN 1047 053464 %IF AP == NULL %THENEXIT 1048 !END OF CHAIN 1049 053466 %IF AP_STATUS # 0 %THENSTART 1050 !IF TERMINAL PROCESS 1051 053500 %IF SOND # 0 %AND SOND # AP_NODE %THEN -> L1 1052 !CHECK MATCH OF NODE IF GIVEN 1053 053514 %IF SOAD > AP_HIGH %THEN -> L1 1054 !CONTINUE ADDRESS HIGHER IN LIST 1055 053524 %IF SOAD < AP_LOW %THEN -> L1 1056 !CONTINUE ADDRESS LOWER 1057 053534 %FINISHELSESTART ; !IF NODE PROCESS 1058 053536 %IF SOND = 0 %THEN SOND = AP_NODE 1059 !IF SOURCE NODE NOT GIVEN 1060 %FINISH 1061 053552 SO == AP; !SET SOURCE POINTER 1062 053556 %IF SOND = 0 %THEN SOND = SO_NODE 1063 !SET NODE IF NOT GIVEN 1064 053572 SOP = SO_STATUS 1065 053606 %RETURN 1066 053612 L1: %REPEAT 1067 053614 %FINISHELSESTART ; !FIND BY SINK ADDRESS 1068 053616 AP == C(-2); BEST == NULL 1069 %CYCLE 1070 053634 LAP == AP 1071 053642 AP == AP_GLINK 1072 053654 %IF AP == NULL %THENEXIT 1073 053656 %IF AP_NODE > SIND %THENEXIT ; !EXIT, NODE LOWER IN LIST SO 1074 ! DOESNT EXIST 1075 053672 %IF SIND = AP_NODE %AND SIAD <= AP_HIGH %THENSTART 1076 053712 %IF SIAD < AP_LOW %THENEXIT 1077 !EXIT, ADDRESS TOO LOW 1078 053722 %UNLESS ALT == NULL %THENSTART 1079 053730 %IF ALT == AP %THEN ALT == NULL 1080 053740 %FINISHELSESTART 1081 053742 %IF BEST == NULL %THENSTART 1082 053750 BEST == AP; HEAD == LAP; LAP1 == LAP 1083 053770 %FINISHELSESTART 1084 053772 %IF SCORE(AP) < SCORE(BEST) %THENSTART 1085 054022 BEST == AP; LAP1 == LAP 1086 %FINISH 1087 %FINISH 1088 %FINISH 1089 054036 %IF FLG >= 0 %THENEXIT 1090 %FINISH 1091 054044 %REPEAT 1092 054046 ALT == NULL 1093 054052 %UNLESS BEST == NULL %THENSTART 1094 054060 LAP1_GLINK == BEST_GLINK 1095 054072 BEST_GLINK == HEAD_GLINK 1096 054104 HEAD_GLINK == BEST 1097 054110 AP == BEST; SI == AP; LAP == HEAD 1098 054130 %IF SI_PROC = 0 %THEN SI == SI_CPTR_LINK 1099 !SELECT ROUTE IF INDIRECT 1100 054150 SIP = SI_STATUS 1101 054170 %RETURN 1102 %FINISH 1103 %FINISH 1104 054174 AP == NULL; !SET AP==NULL TO INDICATE NOTHING 1105 ! FOUND 1106 054200 %END 1107 1108 1109 054204 %ROUTINE CCBGET(%INTEGER FLG) 1110 !LOOK UP CONNECT CONTROL 1111 ! BLOCK ON CCB CHAIN OF 1112 ! SOURCE OR SINK 1113 !FLG=0 - LOOKUP BY PORT 1114 !FLG=1 - LOOKUP BY FACILITY 1115 ! NUMBER 1116 %INTEGER AD, ND, D 1117 %RECORDFORMAT CPXF(%INTEGER LINK1, %RECORD (APF) %NAME PTR0, %C 1118 PTR1, %INTEGER ADDR0, ADDR1, NODE) 1119 %RECORD (CPXF) %NAME CPX 1120 %RECORD (LCPXF) %NAME LCPX 1121 054222 %IF FLG <= 0 %OR FR = 0 %THEN AD = SOAD %AND ND = SOND %C 1122 %ELSE AD = SIAD %AND ND = SIND 1123 054270 %IF FLG <= 0 %THENSTART ; !FIND BY PORT 1124 054274 LCP == SO_CPTR 1125 %CYCLE 1126 054310 CPX == LCP_LINK 1127 054320 %IF CPX == NULL %OR CPX_ADDR1 = AD %THENEXIT 1128 054340 LCP == CPX 1129 054344 %REPEAT 1130 054346 %FINISHELSESTART ; !FIND BY FACILITY 1131 054350 LCP == C(-3) 1132 %CYCLE 1133 054362 CPX == LCP_LINK 1134 054372 %IF CPX == NULL %OR (CPX_ADDR0 = AD %AND CPX_NODE = %C 1135 ND %AND CPX_PTR1 == SO) %THENEXIT 1136 054432 LCP == CPX 1137 054436 %REPEAT 1138 %FINISH 1139 054440 CP == CPX 1140 054446 %IF CP == NULL %OR FLG < 0 %THENRETURN 1141 054462 LCPX == LCP 1142 054466 CPN = (LCPX_LINK-CBASE) >> 1 1143 054504 ORIG = CPN&1 1144 054514 NOTORIG = 1-ORIG 1145 054526 CP == C(CPN-ORIG) 1146 054550 STATE = CP_STATE 1147 054556 SI == CP_PTR(NOTORIG)_LINK 1148 054570 %IF FLG = 0 %THEN SIND = SI_NODE 1149 054610 SIP = SI_STATUS 1150 054630 SIAD = CP_ADDR(NOTORIG) 1151 054650 %END 1152 1153 1154 054654 %ROUTINE ISSUE(%INTEGER F, Q) 1155 !ISSUE FUNCTION F WITH FLAGS 1156 ! OR FAIL QUAL Q 1157 !IF ORIG=0 SEND IT TO CONNECT 1158 ! RESPONDER (IE FROM ORIGINATOR) 1159 !IF ORIG=1 SEND IT TO CONNECT 1160 ! ORIGINATOR (IE FROM RESPONDER) 1161 %RECORD (MPF) %NAME IP 1162 %RECORD (APF) %NAME PP 1163 054672 IP == GETSPACE(8) 1164 054706 PP == CP_PTR(NOTORIG)_LINK 1165 054726 IP_FN = F 1166 054734 %IF STATE < 5 %THENSTART ; !FACILITY STATE 1167 054744 IP_ADDR1 = CP_ADDR(0) 1168 054756 IP_NODE1 = CP_NODE 1169 054764 IP_ADDR2 = CP_ADDR(1) 1170 054772 IP_NODE2 = MYNODE 1171 055000 %FINISHELSESTART 1172 055002 IP_ADDR1 = CP_ADDR(NOTORIG) 1173 055022 IP_ADDR2 = IP_ADDR1 1174 055030 %IF F >= 0 %THEN IP_NODE1 = MYNODE %AND IP_NODE2 = %C 1175 PP_NODE %ELSE IP_NODE1 = PP_NODE %AND IP_NODE2 = MYNODE 1176 !FOR COMPATIBILITY ONLY - 1177 ! ELSE ZERO 1178 %FINISH 1179 055100 %IF F&127 = 6 %THENSTART 1180 !IF NIF 1181 055116 IP_SFLAGS = Q&128 1182 055132 IP_UFLAGS = FN+FR 1183 !SET FLAGS WORD - DISCONNECT 1184 ! BIT + FAILING FUNCTION NO 1185 055146 IP_SF = Q!128; !SET FAIL QUALIFIER 1186 055162 %FINISHELSESTART ; !IF OTHER FN 1187 055164 IP_SFLAGS = 0 1188 055170 IP_UFLAGS = 0; !FLAGS ZERO 1189 055174 IP_SF = Q; !SET FAIL QUAL 1190 %FINISH 1191 055202 IP_LEN = 10 1192 055210 MONITOR(IP, PP_LINE, 2); !NIF OR OTHER KERNEL FN ISSUED 1193 055232 SEND(IP, PP_LINE, PP_PROC) 1194 055256 %END 1195 1196 1197 055262 %ROUTINE ACBASSIGN(%INTEGER P) 1198 !ASSIGN ATTACH CONTOL BLOCK 1199 !THE ATTACH CHAIN IS HELD AS 1200 ! A DOUBLY LINKED CHAIN TO 1201 ! EASE DELETIONS 1202 %RECORD (LAPF) %NAME LL 1203 055300 AP == GET; !GET CB 1204 055310 %IF AP == NULL %THENRETURN ; !OUT OF SPACE 1205 055316 AP_GLINK == LAP_GLINK 1206 055330 LAP_GLINK == AP; !ADD TO GLOBAL CHAIN 1207 055334 AP_PLINK == C(P)_LINK 1208 055354 C(P)_LINK == AP; !ADD TO PROCESS CHAIN 1209 055360 AP_CPTR_LINK == NULL; !SET CCB CHAIN EMPTY 1210 055370 ATTACHES = ATTACHES+1 1211 055374 %END 1212 1213 1214 055400 %ROUTINE ACBFREE(%RECORD (APF) %NAME AP) 1215 !DELETE ATTACH CONTROL BLOCK 1216 ! IF REMOVE ISSUED AND NOT IN USE 1217 %RECORD (LCPF) %NAME LL 1218 055416 %IF AP_PROC # 0 %ANDNOT AP_CPTR_LINK == NULL %THEN STOP(6) 1219 055446 %IF AP_BUFFS # 0 %THEN STOP(26) 1220 !COUNTS NOT CONSISTENT 1221 055470 %IF PP == AP %THEN PP == PP_GLINK 1222 !ENSURE PP DOESNT POINT AT 1223 ! DELETED ACB 1224 055512 LAP_GLINK == AP_GLINK; !UNHOOK FROM GLOBAL CHAIN 1225 055530 %IF AP_PROC = 0 %THEN LL == C(-2) %ELSE LL == C(AP_LINE) 1226 055572 %WHILE (%NOT LL_LINK == AP) %CYCLE 1227 055604 %IF LL == NULL %THEN STOP(7) 1228 055620 LL == LL_LINK 1229 055630 %REPEAT 1230 055632 LL_LINK == AP_PLINK; !UNHOOK FROM PROCESS CHAIN 1231 055640 FREE(AP); !RETURN SPACE 1232 055646 ATTACHES = ATTACHES-1 1233 055652 %END 1234 1235 1236 055656 %ROUTINE CCBASSIGN(%INTEGER S) 1237 !ASSIGN CONNECT CONTROL BLOCK 1238 ! IN STATE S 1239 !THE CONNECT CHAIN IS HELD AS 1240 ! TWO SINGLY LINKED CHAINS 1241 !THE CONNECT ORIGINATOR IS 1242 ! LINKED USING LINK1 (EVEN 1243 ! ADDRESS) 1244 !THE CONNECT RESPONDER IS 1245 ! LINKED USING LINK2 (ODD 1246 ! ADDRESS) 1247 055674 CP == GET; !GET CB 1248 055704 %IF CP == NULL %THENRETURN 1249 !OUT OF SPACE 1250 055712 CP_LINK(0)_LINK == SO_CPTR_LINK 1251 055722 SO_CPTR_LINK == CP; !ADD TO SOURCE PORT CHAIN 1252 055726 CP_LINK(1)_LINK == C(-3)_LINK 1253 055740 C(-3)_LINK == CP_LINK(1); !ADD TO FACILITY CHAIN 1254 055750 CP_PTR(0)_LINK == SO 1255 055760 CP_PTR(1)_LINK == SI; !SET SOURCE AND SINK POINTERS 1256 055766 CP_ADDR(0) = SOAD 1257 055774 CP_ADDR(1) = SIAD; !SET SOURCE AND SINK ADDRESSES 1258 056002 CP_STATE = S; !SET STATE 1259 056010 CP_NODE = SOND 1260 056016 CONNECTS = CONNECTS+1 1261 056022 %END 1262 1263 1264 056026 %ROUTINE CCBFREE(%INTEGER NS) 1265 !DELETES A CONNECT CONTROL BLOCK 1266 !LCP WILL POINT TO THE 1267 ! PREVIOUS CCB ON ONE CHAIN 1268 !THE OTHER PRECEDING CCB MUST 1269 ! BE FOUND BY CHAIN CHASING 1270 %INTEGER I, J, S 1271 %RECORD (LCPF) %ARRAY LL(0:1) 1272 %RECORD (LCPF) %NAME LL1 1273 %RECORD (APF) %NAME PP 1274 056044 S = CP_STATE; !CURRENT STATE 1275 056056 LL(0)_LINK == LCP 1276 056064 LL(1)_LINK == LCP 1277 056072 %IF NS = 0 %AND (S = 1 %OR S = 3 %OR 6 <= S <= 7) %THENSTART 1278 !FIND OTHER CHAIN LINK 1279 056140 %IF LCP_LINK == CP %THEN I = 1 %ELSESTART 1280 056160 %IF LCP_LINK == CP_LINK(1) %THEN I = 0 %ELSE STOP(8) 1281 !LCP NOT CORRECT ?? 1282 %FINISH 1283 056206 PP == CP_PTR(I)_LINK; LL1 == PP_CPTR 1284 !CHASE ORIG CHAIN OR RESP CHAIN 1285 056242 %WHILE (%NOT LL1_LINK == CP_LINK(I)) %CYCLE 1286 056264 LL1 == LL1_LINK 1287 056270 %IF LL1 == NULL %THEN STOP(9) 1288 !NOT ON CHAIN ?? 1289 056302 %REPEAT 1290 056304 LL(I)_LINK == LL1 1291 %FINISH 1292 056320 %CYCLE I = 0, 1, 1; !DELETE FROM ORIG CHAIN AND/OR 1293 !RESP CHAIN 1294 056342 %IF LL(I)_LINK_LINK == CP_LINK(I) %THENSTART 1295 !CAN WE DELETE FROM THIS CHAIN 1296 056374 LL(I)_LINK_LINK == CP_LINK(I)_LINK 1297 !UNHOOK FROM CHAIN 1298 056414 J = CP_LIM(I); !BUFFERS 1299 056440 BC = BC-J 1300 !RETURN TO GLOBAL COUNT 1301 056444 PP == CP_PTR(I)_LINK 1302 056464 PP_BUFFS = PP_BUFFS-J-1 1303 !RETURN TO ACB 1304 %FINISH 1305 056504 %REPEAT 1306 056506 %IF CP_STATE >= 5 %THEN MONITOR(CP, 0, 6) 1307 !MONITOR DISCONNECT 1308 056536 CP_STATE = NS; !SET NEW STATE 1309 056550 %IF NS > 0 %THENRETURN 1310 056562 FREE(CP); !FREE CCB IF DISCONNECTED 1311 056570 BC = BC-1; !COUNT ONE FOR EACH CONNECT 1312 056574 CONNECTS = CONNECTS-1 1313 056600 %END 1314 1315 1316 056604 %ROUTINE SETUPQUOTE(%RECORD (APF) %NAME PP, %RECORD (MPF) %C 1317 %NAME QQ, %INTEGER REPLY) 1318 !SEND ROUTING INFORMATION 1319 !P=LINK DOWN WHICH QUOTE IS 1320 ! TO SENT 1321 !Q=EXISTING PACKET FOR REPLY 1322 %INTEGER I, K, L, N1 1323 %CONSTINTEGER RMAX = 256 1324 %RECORD (APF) %NAME JJ 1325 056622 %IF REPLY = 0 %THENSTART ; !NEW QUOTE TO BE ISSUED 1326 056630 QQ_FN = 2 1327 056642 QQ_NODE1 = MYNODE 1328 056650 QQ_ADDR1 = ROUTEADDR 1329 056656 QQ_NODE2 = PP_NODE 1330 056670 QQ_ADDR2 = ROUTEADDR 1331 %FINISH 1332 056676 QQ_SFLAGS = 0 1333 056706 QQ_UFLAGS = 0 1334 056712 QQ_SF = 0 1335 056716 QQ_LEN = 14 1336 056724 QQ_DATA(0) = 0 1337 056730 QQ_DATA(1) = 0 1338 056734 QQ_DATA(2) = 0 1339 056740 QQ_DATA(3) = SCORE(PP); !SEND OUR LINK SCORE, NOT 1340 ! USED MEANTIME 1341 056764 I = 0; N1 = 0 1342 056774 JJ == C(-1)_LINK 1343 057002 %WHILE (%NOT JJ == NULL) %CYCLE 1344 !SET UP QUOTATION NODE BY 1345 057010 %UNLESS JJ == PP %OR JJ_NODE = 0 %OR JJ_NODE < N1 %THENSTART 1346 057032 %IF JJ_NODE = N1 %THENSTART 1347 057040 L = SCORE(JJ) 1348 057052 %IF K > L %ANDNOT JJ_CPTR_LINK == PP %THEN %C 1349 K = L 1350 057100 %FINISHELSESTART 1351 057102 N1 = JJ_NODE 1352 057106 K = SCORE(JJ); !ADD LOAD FACTOR TO QUOTES 1353 057120 %IF JJ_CPTR_LINK == PP %THEN K = 255 1354 !SET SCORE TO MAX IF VIA 1355 ! CURRENT LINK 1356 057142 I = I+2 1357 057150 %IF I >= RMAX-20 %THENEXIT 1358 057160 QQ_LEN = QQ_LEN+2 1359 %FINISH 1360 057204 QQ_DATA(I+2) = N1 1361 057222 QQ_DATA(I+3) = K 1362 %FINISH 1363 057240 JJ == JJ_GLINK; !STEP THROUGH NODES (BACKWARDS) 1364 057252 %REPEAT 1365 057254 %END 1366 1367 1368 1369 057260 %INTEGERFN SCORE(%RECORD (APF) %NAME TAP) 1370 %INTEGER S 1371 057276 LF = BC//LFACTOR 1372 057314 S = TAP_SCORE+LF 1373 057332 %IF TAP_PROC = 0 %THEN TAP == TAP_CPTR_LINK 1374 057346 %IF TAP_BUFFS >= TAP_LIMIT %THENRESULT = 250 1375 057372 %RESULT = S+TAP_BUFFS//LFACTOR 1376 %END 1377 1378 057414 %RECORD (LCPF) %MAP GET 1379 !ASSIGN SPACE FROM FREE CHAIN 1380 %RECORD (APF) %NAME II 1381 057432 %IF FL == NULL %THENRESULT == NULL 1382 057452 II == FL 1383 057456 FL == FL_LINK 1384 057466 II = 0 1385 057476 II_SEQNO = SEQNO 1386 057510 SEQNO = SEQNO+1 1387 057514 %RESULT == II 1388 %END 1389 1390 1391 057520 %ROUTINE FREE(%RECORD (LAPF) %NAME II) 1392 057536 II_PLINK == FL 1393 057546 II_GLINK == EMPTY 1394 057554 FL == II 1395 057560 %END 1396 057564 %ENDOFPROGRAM