|
|
1.1 ! root 1: ! 2: /* ! 3: * Input Segment ! 4: */ ! 5: .org 2048 ! 6: seg2: ! 7: in: ! 8: CHK(B2_ENT,2) /* check point */ ! 9: SENDCMD(D_READ) /* for dr11-c version */ ! 10: ! 11: i_csrtst: ! 12: /* ! 13: * While there is data in the receiver fifo ! 14: * copy it out ! 15: * While (dkcsr & DKRDONE) { ! 16: */ ! 17: READDATA(i_disp) ! 18: /* ! 19: * Scan for the 1st word of a packet where a channel # ! 20: * in the low byte and DKMARK in the hi byte ! 21: * If not the packet marker, just throw it away and repeat ! 22: */ ! 23: mov ILO,r9 /* read chan # */ ! 24: mov IHI,brg /* read hi byte and strobe */ ! 25: br1 i_mark ! 26: DELAY(3) ! 27: br i_csrtst ! 28: ! 29: i_mk4: ! 30: /* ! 31: * a data in odl left over from last chan# (r9) ! 32: */ ! 33: CALL(copy1,s.copy1) ! 34: br i_mk7 ! 35: i_mk5: ! 36: /* ! 37: * for char mode, check for timeout ! 38: */ ! 39: CALL(cktimer,s.cktimer) ! 40: br i_mk8 ! 41: i_mk6: ! 42: /* ! 43: * see a DKMARK again ! 44: * r13 and r12 can't be destroyed elsewhere e.g. 'rcv' ! 45: */ ! 46: mov r1,brg ! 47: addn brg,r9,- ! 48: brz i_lp0 ! 49: mov r12,brg ! 50: br0 i_mk4 /* copy the left-over byte in odl */ ! 51: i_mk7: ! 52: /* ! 53: * if the previous channel was in char mode and timeout mode, ! 54: * then do timeout processing ! 55: */ ! 56: asl r13,brg ! 57: br7 i_mk5 /* char mode */ ! 58: i_mk8: ! 59: mov r1,brg ! 60: mov brg,r9 ! 61: i_mark: ! 62: /* ! 63: * We found the 1st word, the channel # is in r9 ! 64: * If the channel # is 377 (all 1's), that means ! 65: * probably power failed or module fell out of bin ! 66: */ ! 67: dec r9,- ! 68: brz i_incomp ! 69: mov CHANMODS,brg ! 70: sub brg,r9,- /* chan# - CHANMODS */ ! 71: brc i_incomp ! 72: GLTE(r9) /* set up r8/r10 */ ! 73: /* ! 74: * r13: a global flag in input.s ! 75: * bit 7 - RBLEN > 0 (or C_RB != NULL) ! 76: * bit 6 - char mode ! 77: * bit 4 - C_TA0 != 0 ! 78: * bit 1 - RLEN == 0 ! 79: * bit 0 - RADDR is odd ! 80: * r12: a global flag in input.s ! 81: * bit 0 - odl has the 1st byte of a pair ! 82: * r15: report mode ! 83: */ ! 84: mov 0,brg ! 85: mov brg,r13 ! 86: mov brg,r12 ! 87: mov C_RB,brg ! 88: add brg,r10,mar ! 89: mov mem,brg ! 90: brz 1f ! 91: mov (1<<7),brg ! 92: or brg,r13 ! 93: 1: ! 94: mov C_X1,brg ! 95: add brg,r10,mar ! 96: mov mem,r0 ! 97: mov XBLK,brg ! 98: orn brg,r0,- ! 99: brz 1f ! 100: mov (1<<6),brg ! 101: or brg,r13 ! 102: 1: ! 103: mov C_TA0,brg ! 104: add brg,r10,mar ! 105: mov mem,r0 ! 106: dec r0,- ! 107: brz 1f ! 108: mov (1<<4),brg ! 109: or brg,r13 ! 110: 1: ! 111: mov C_RLEN,brg ! 112: add brg,r10,mar ! 113: mov mem,r0|mar++ ! 114: or mem,r0,r0|mar++ ! 115: dec r0,- ! 116: brc 1f ! 117: mov (1<<1),brg ! 118: or brg,r13 ! 119: 1: ! 120: mov mem,brg ! 121: br0 1f ! 122: br i_loop ! 123: 1: ! 124: mov (1<<0),brg ! 125: or brg,r13 ! 126: i_lp0: ! 127: /* ! 128: * add possible delay for null byte ! 129: */ ! 130: DELAY(0) ! 131: D422(1) ! 132: i_loop: ! 133: /* ! 134: * main loop to read the rest of the packet ! 135: * see if a control envelop or data envelop ! 136: */ ! 137: D422(0) ! 138: READDATA(i_id6) ! 139: mov ILO,r1 ! 140: mov IHI,brg ! 141: br1 i_mk6 /* see DKMARK again */ ! 142: br0 i_data ! 143: /* ! 144: * A good control envelop is detected for chan # (in r9) ! 145: * control data in r1 ! 146: * if 1 <= r1 <= 010, interface module cntl ! 147: * if 010 <= r1 <= 077, protocol cntl ! 148: * if 0100 <= r1 <= 0177, user cntl ! 149: * if r1 >= 0200, supervision cntl ! 150: */ ! 151: dec r1,- ! 152: brz i_lp0 /* null byte */ ! 153: CHK(B2_CNTL,2) /* check point */ ! 154: /* ! 155: * if r12.0 call copy1, adjust r13 ! 156: */ ! 157: mov r12,brg ! 158: br0 i_lp4 ! 159: i_lp2: ! 160: mov r1,brg ! 161: br7 i_tdkcl ! 162: mov 0277,brg /* 6-th bit is not set */ ! 163: or brg,r1,brg ! 164: brz i_ucntl ! 165: /* ! 166: * this is a protocol cntl char ! 167: * r5 = r1 & WINDOW ! 168: * r0 = r1 & 0370 ! 169: */ ! 170: mov 0370,brg ! 171: and brg,r1,brg ! 172: mov brg,r0 ! 173: mov WINDOW,brg ! 174: and brg,r1,brg ! 175: mov brg,r5 ! 176: /* ! 177: * switch (r0) { ! 178: * case ..... ! 179: */ ! 180: mov I_SEQ,brg ! 181: addn brg,r0,- ! 182: brz i_seq ! 183: mov I_ECHO,brg ! 184: addn brg,r0,- ! 185: brz i_echo ! 186: mov I_ACK,brg ! 187: addn brg,r0,- ! 188: brz i_ack ! 189: mov I_BOT,brg ! 190: addn brg,r0,- ! 191: brz i_050 ! 192: mov I_REJ,brg ! 193: addn brg,r0,- ! 194: brz i_rej ! 195: mov I_AINIT,brg ! 196: addn brg,r1,- ! 197: brz i_ainit ! 198: mov I_INIT1,brg ! 199: addn brg,r1,- ! 200: brz i_init ! 201: mov I_INIT0,brg ! 202: addn brg,r1,- ! 203: brz i_init ! 204: i_umeta: ! 205: /* ! 206: * un-recognized meta char ! 207: */ ! 208: /* ! 209: ERROR(E_UMETA) ! 210: */ ! 211: br i_loop ! 212: i_tdkcl: ! 213: /* ! 214: * code overflow to output.s ! 215: */ ! 216: mov %ii_tdkcl,brg ! 217: mov brg,pcr ! 218: jmp ii_tdkcl ! 219: ! 220: i_ucntl: ! 221: /* ! 222: * rcv a user cntl char ! 223: * if (r12.0) then copy odl to raddr first ! 224: * set idh to 0 and goto id9 ! 225: */ ! 226: CHK1(B2_SUP,2) ! 227: mov 0,brg ! 228: mov brg,idh /* indicate cntl */ ! 229: br i_id9 /* copy to C_RB */ ! 230: ! 231: i_lp4: ! 232: CALL(copy1,s.copy1) ! 233: br i_lp2 ! 234: ! 235: i_050: ! 236: mov sw050,brg ! 237: br (add,brg,r5),%sw050 ! 238: sw050: ! 239: br i_bot ! 240: br i_botm ! 241: br i_bots ! 242: br i_soi ! 243: br i_eoi ! 244: br i_enq ! 245: br i_check ! 246: br i_initreq ! 247: i_init: ! 248: /* ! 249: * code overflow to output.s ! 250: */ ! 251: mov %ii_init,brg ! 252: mov brg,pcr ! 253: jmp ii_init ! 254: i_ainit: ! 255: /* ! 256: * code overflow to output.s ! 257: */ ! 258: mov %ii_ainit,brg ! 259: mov brg,pcr ! 260: jmp ii_ainit ! 261: i_initreq: ! 262: /* ! 263: * code overflow to output.s ! 264: */ ! 265: mov %ii_req,brg ! 266: mov brg,pcr ! 267: jmp ii_req ! 268: i_enq: ! 269: /* ! 270: * code overflow to output.s ! 271: */ ! 272: mov %ii_enq,brg ! 273: mov brg,pcr ! 274: jmp ii_enq ! 275: i_check: ! 276: /* ! 277: * code overflow to output.s ! 278: */ ! 279: mov %ii_check,brg ! 280: mov brg,pcr ! 281: jmp ii_check ! 282: ! 283: i_bot: ! 284: i_botm: ! 285: i_bots: ! 286: i_soi: ! 287: /* ! 288: * TA0 = r1; TA1 = 0; ! 289: */ ! 290: CHK(B4_BOT,4) ! 291: mov r8,%mar ! 292: mov C_TA0,brg ! 293: add brg,r10,mar ! 294: mov r1,mem|mar++ ! 295: mov 0,mem ! 296: mov (1<<4),brg ! 297: or brg,r13 ! 298: br i_loop ! 299: i_eoi: ! 300: /* ! 301: * code overflow to output.s ! 302: */ ! 303: mov %ii_eoi,brg ! 304: mov brg,pcr ! 305: jmp ii_eoi ! 306: ! 307: i_rej: ! 308: /* ! 309: * if XENQ is set, then treat this REJ as ECHO ! 310: * otherwise ignore this REJ ! 311: */ ! 312: mov r8,%mar ! 313: mov C_X1,brg ! 314: add brg,r10,mar ! 315: mov mem,r0 ! 316: mov ~XENQ,brg ! 317: or brg,r0,- ! 318: brz i_ec0 /* XENQ is set, no ECHO was rcv */ ! 319: br i_loop /* ignore this REJ */ ! 320: i_echo: ! 321: /* ! 322: * R = r5; ! 323: * if ((S-R-1)&07 < (S-A-1)&07) { ! 324: * len1 = r5 - A; ! 325: * X &= ~XREJ; A = r5; ! 326: * if (len1==0) goto i_rej1; ! 327: * len2 = (len1)*DKBLOCK; ! 328: * ...... ! 329: * } ! 330: */ ! 331: CHK(B3_ECHO,3) ! 332: mov r8,%mar ! 333: mov C_X1,brg ! 334: add brg,r10,mar ! 335: mov mem,r0 ! 336: mov ~XENQ,brg ! 337: i_ec0: ! 338: and brg,r0,mem /* reset XENQ */ ! 339: mov C_S,brg ! 340: add brg,r10,mar ! 341: mov mem,r3 ! 342: mov mem,r4|mar++ /* r4, r3 = S */ ! 343: mov r5,mem /* R = r5 */ ! 344: addn mem,r4,r4|mar++ /* r4 = S-R-1 */ ! 345: addn mem,r3 /* r3 = S-A-1 */ ! 346: mov WINDOW,brg ! 347: and brg,r4 ! 348: and brg,r3,brg ! 349: sub brg,r4,- ! 350: brc i_rej1 /* (S-R-1) >= (S-A-1) */ ! 351: i_gack: ! 352: mov mem,r2 /* r2 = old A */ ! 353: mov r5,mem /* A = r5 */ ! 354: mov C_X1,brg ! 355: add brg,r10,mar ! 356: mov mem,r0 ! 357: mov ~XREJ,brg ! 358: and brg,r0,mem /* X &= ~XREJ */ ! 359: /* ! 360: * if XLEN==0 and XCNTL==0, xmit is inactive, discard this ECHO/REJ ! 361: */ ! 362: mov C_XLEN,brg ! 363: add brg,r10,mar ! 364: mov mem,r0|mar++ ! 365: or mem,r0 ! 366: dec r0,- ! 367: brc 1f ! 368: mov C_XCNTL,brg ! 369: add brg,r10,mar ! 370: mov mem,r0 ! 371: dec r0,- ! 372: brz i_xnil /* check if trailer only mode */ ! 373: 1: ! 374: mov r2,brg ! 375: sub brg,r1,brg ! 376: mov brg,r2 /* r2 = r1 - old A */ ! 377: mov WINDOW,brg ! 378: and brg,r2 /* r2 = len1 */ ! 379: dec r2,- ! 380: brz i_rej1 ! 381: mov DKBLOCK,brg ! 382: mov brg,r3 ! 383: TIMES(r2,r3,r7,r6) /* r7/6 (len2) = r2 * r3 */ ! 384: /* ! 385: * if (len2>XLEN) { XLEN=0; report; } ! 386: * else if (len2=XLEN) { XLEN=0; report if ~XCNTL; } ! 387: * else if (len2<XLEN) { XLEN -= len2; XADDR =+ len2; } ! 388: */ ! 389: mov C_XLEN,brg ! 390: add brg,r10,mar ! 391: mov mem,r3 ! 392: mov r6,brg ! 393: sub brg,r3,mem ! 394: mov mem,r0|mar++ ! 395: mov mem,r4 ! 396: mov r7,brg ! 397: subc brg,r4,mem ! 398: brc i_ec2 /* XLEN >= len2 */ ! 399: i_ec1: ! 400: /* ! 401: * This chan has done the transmission ! 402: * remove chan# from 'outq' and report ! 403: */ ! 404: mov C_XLEN,brg ! 405: add brg,r10,mar ! 406: mov 0,mem|mar++ ! 407: mov 0,mem ! 408: mov C_XCNTL,brg ! 409: add brg,r10,mar ! 410: mov 0,mem ! 411: mov %repinfo,%mar ! 412: mov repinfo,mar ! 413: mov KS_SEND,mem ! 414: CALL(report,s.report) ! 415: /* ! 416: * remove chan# from 'outq' ! 417: * r2: running ptr of outq, r3: next ptr in outq, r4: ptr of outq1 ! 418: */ ! 419: mov outq,mar ! 420: mov %outq,%mar ! 421: mov mem,r2 ! 422: 0: ! 423: brz 6f ! 424: QA(r2) ! 425: mov mem,r3 ! 426: mov NIL,mem|mar++ ! 427: addn mem,r9,- ! 428: brz 5f ! 429: mov outq1,mar ! 430: mov %outq1,%mar ! 431: 1: ! 432: mov mem,r4 ! 433: brz 2f ! 434: QA(r4) ! 435: br 1b ! 436: 2: /* put r2 at the end of outq1 */ ! 437: mov r2,mem ! 438: 3: /* put r3 to r2 */ ! 439: mov r3,brg ! 440: mov brg,r2 ! 441: br 0b ! 442: 5: /* delete this chan# */ ! 443: FREEQ(r2) ! 444: br 3b ! 445: 6: /* restore outq from outq1 */ ! 446: mov outq1,mar ! 447: mov %outq1,%mar ! 448: mov mem,brg ! 449: mov outq,mar ! 450: mov %outq,%mar ! 451: mov brg,mem|mar++ ! 452: mov NIL,mem ! 453: mov r8,%mar ! 454: br i_rej1 ! 455: i_ec2: ! 456: /* ! 457: * len2 <= XLEN ! 458: */ ! 459: or mem,r0,r0|mar++ ! 460: dec r0,- ! 461: brc i_ec3 /* len2 < XLEN */ ! 462: /* ! 463: * len2 = XLEN: check if XCNTL is user cntl ! 464: */ ! 465: mov C_XCNTL,brg ! 466: add brg,r10,mar ! 467: mov mem,r0 ! 468: mov 0300,brg ! 469: and brg,r0 ! 470: mov 0100,brg ! 471: addn brg,r0,- ! 472: brz i_rej1 /* don't report */ ! 473: br i_ec1 ! 474: i_ec3: ! 475: /* ! 476: * len2 < XLEN ! 477: * C_XADDR += len2; ! 478: */ ! 479: mov 0,r0 ! 480: add mem,r6,mem|mar++ ! 481: addc mem,r7,mem|mar++ ! 482: addc mem,r0,mem ! 483: i_rej1: ! 484: /* ! 485: * if REJ && (X&XREJ==0) ! 486: */ ! 487: mov ~I_REJ,brg ! 488: or brg,r1,brg ! 489: brz 1f ! 490: br i_loop ! 491: 1: ! 492: mov C_X1,brg ! 493: add brg,r10,mar ! 494: mov mem,r0 ! 495: mov ~XREJ,brg ! 496: or brg,r0,- ! 497: brz i_loop /* if REJ had been rcv, ignore this REJ */ ! 498: i_grej: ! 499: /* ! 500: * rcv a REJ: S=(r5+1)&WINDOW, X |= XREJ; ! 501: */ ! 502: CHK1(B3_REJ,3) ! 503: inc r5 ! 504: mov C_S,brg ! 505: add brg,r10,mar ! 506: mov WINDOW,brg ! 507: and brg,r5,mem ! 508: mov C_X1,brg ! 509: add brg,r10,mar ! 510: mov XREJ,brg ! 511: mov brg,r0 ! 512: or mem,r0,mem ! 513: /* ! 514: * if XNIL, call strailer, else loop ! 515: */ ! 516: mov ~XNIL,brg ! 517: or brg,r0,- ! 518: brz 1f ! 519: br i_loop ! 520: 1: ! 521: CALL(strailer,s.strailer) ! 522: br i_loop ! 523: i_xnil: ! 524: /* ! 525: * if XNIL, report completion, else loop ! 526: */ ! 527: mov C_X1,brg ! 528: add brg,r10,mar ! 529: mov mem,r0 ! 530: mov XNIL,brg ! 531: orn brg,r0,- ! 532: brz 1f ! 533: br i_loop /* rcv suspicious ECHO */ ! 534: 1: xor brg,r0,mem /* reset XNIL bit */ ! 535: br i_ec1 /* report KS_SEND */ ! 536: ! 537: i_ack: ! 538: /* ! 539: * if (r5!=A) goto i_gack; ! 540: * if ((X&XREJ) == 0)) goto i_grej; ! 541: * break; ! 542: */ ! 543: CHK(B3_ACK,3) ! 544: mov r8,%mar ! 545: mov C_X1,brg ! 546: add brg,r10,mar ! 547: mov mem,r4 ! 548: mov ~XACK,brg ! 549: and brg,r4,mem ! 550: mov C_A,brg ! 551: add brg,r10,mar ! 552: addn mem,r5,- ! 553: brz 1f ! 554: br i_gack ! 555: 1: ! 556: mov (XREJ|XACK),brg ! 557: and brg,r4 ! 558: dec r4,- ! 559: brz i_grej ! 560: br i_loop ! 561: ! 562: i_seq: ! 563: /* ! 564: * pseq = ECHO + r5; ! 565: * check if char or block mode processing ! 566: * r13.6 == 0 block mode, else char mode ! 567: */ ! 568: CHK(B3_SEQ,3) ! 569: mov 0,brg ! 570: mov brg,r15 /* report mode */ ! 571: mov r8,%mar ! 572: asl r13,brg /* bit 6 of r13 is char mode */ ! 573: br7 i_seq2 ! 574: /* ! 575: * BLOCK mode: ! 576: * check if trailer is well formed and len is correct: ! 577: */ ! 578: mov C_TA0,brg ! 579: add brg,r10,mar ! 580: mov mem,r7|mar++ ! 581: mov mem,r6|mar++ ! 582: dec r7,- ! 583: brz i_nwwt ! 584: mov I_SOI,brg ! 585: addn brg,r7,- ! 586: brz i_nwwt ! 587: mov 2,brg ! 588: addn brg,r6,- ! 589: brz 1f ! 590: br i_nwwt ! 591: 1: ! 592: mov mem,r0|mar++ /* TA2 */ ! 593: mov mem,r6 /* TA3 */ ! 594: mov C_RBLEN,brg ! 595: add brg,r10,mar ! 596: mov mem,r3|mar++ ! 597: mov mem,r2 ! 598: mov C_RULEN,brg ! 599: add brg,r10,mar ! 600: add mem,r3,brg|mar++ ! 601: addc mem,r2 ! 602: sub brg,r0 ! 603: mov r2,brg ! 604: subc brg,r6,brg ! 605: or brg,r0 ! 606: dec r0,- ! 607: brc i_nwwt ! 608: mov C_RSEQ,brg ! 609: add brg,r10,mar ! 610: mov mem,r0 ! 611: inc r0 ! 612: mov WINDOW,brg ! 613: and brg,r0,brg ! 614: addn brg,r5,- ! 615: brz i_sq2.1 ! 616: br i_nwwt ! 617: i_seq2: ! 618: /* ! 619: * has rcv a good block ! 620: * C_RSEQ = r5; ! 621: */ ! 622: mov C_RSEQ,brg ! 623: add brg,r10,mar ! 624: i_sq2.1: ! 625: mov r5,mem ! 626: /* ! 627: * if (RB==NIL & RQ==NIL & (RLEN!=0 | RULEN!=0)), echo the seq# now ! 628: */ ! 629: mov C_RQ,brg ! 630: add brg,r10,mar ! 631: mov mem,r2 ! 632: mov C_RB,brg ! 633: add brg,r10,mar ! 634: and mem,r2 ! 635: brz 1f ! 636: br i_sq2.3 ! 637: 1: mov C_RLEN,brg ! 638: add brg,r10,mar ! 639: mov mem,r2|mar++ ! 640: or mem,r2 ! 641: mov C_RULEN,brg ! 642: add brg,r10,mar ! 643: or mem,r2,r2|mar++ ! 644: or mem,r2 ! 645: dec r2,- ! 646: brz i_sq2.2 ! 647: mov I_ECHO,brg ! 648: or brg,r5,brg ! 649: mov brg,r1 ! 650: CALL(send,s.send) ! 651: mov r8,%mar ! 652: mov C_C,brg ! 653: add brg,r10,mar ! 654: mov r1,mem ! 655: asl r13,brg ! 656: br7 i_loop /* go if char mode */ ! 657: /* ! 658: * if TA0 (r7) != BOTM, interrupt with SBLOCK ! 659: */ ! 660: mov I_BOTM,brg ! 661: addn brg,r7,- ! 662: brz i_sq2.8 ! 663: /* ! 664: * see if YBLOCK is set ! 665: */ ! 666: mov C_Y,brg ! 667: add brg,r10,mar ! 668: mov mem,r0 ! 669: mov YBLOCK,brg ! 670: orn brg,r0,- ! 671: brz 1f ! 672: br i_sq2.8 ! 673: 1: ! 674: /* ! 675: * interrupt RCV completion with SBLOCK ! 676: */ ! 677: mov SBLOCK,brg ! 678: or brg,r15 ! 679: br i_sq2.8 ! 680: i_sq2.2: ! 681: mov C_RB,brg ! 682: add brg,r10,mar ! 683: i_sq2.3: ! 684: /* ! 685: * put seq# at the end of C_RB ! 686: * mar/%mar now points to C_RB ! 687: */ ! 688: mov mem,r2 ! 689: brz i_sq9.5 ! 690: i_sq2.4: ! 691: /* ! 692: * block mode if r13.6==0 ! 693: * at least part of the data is in stage-1 (RB: r2) buffer ! 694: * if TA0 (r7) != BOTM, pseq = I_SEQ + r5 ! 695: */ ! 696: mov mem,r3 ! 697: 1: ! 698: QA(r3) ! 699: mov mem,r3|mar++ ! 700: brz 2f ! 701: br 1b ! 702: 2: ! 703: mov mem,mem|mar++ /* plen */ ! 704: mov mem,mem|mar++ /* *pdata */ ! 705: asl r13,brg ! 706: br7 i_sq9.3 /* char mode */ ! 707: /* ! 708: * block mode ! 709: */ ! 710: mov I_BOTM,brg ! 711: addn brg,r7,- ! 712: brz 1f ! 713: mov I_SEQ,mem ! 714: br 2f ! 715: 1: mov I_ECHO,mem ! 716: 2: or mem,r5,mem /* pseq */ ! 717: /* ! 718: * put this queue (r2) to end of C_RQ ! 719: */ ! 720: mov r8,%mar ! 721: mov C_RQ,brg ! 722: add brg,r10,mar ! 723: 1: ! 724: mov mem,r0 ! 725: brz 2f ! 726: QA(r0) ! 727: br 1b ! 728: 2: ! 729: mov r2,mem ! 730: mov r8,%mar ! 731: i_sq2.8: ! 732: /* ! 733: * if RULEN==0, no data have been copied to RADDR ! 734: */ ! 735: mov C_RULEN,brg ! 736: add brg,r10,mar ! 737: mov mem,r0 ! 738: mov 0,mem|mar++ ! 739: or mem,r0 ! 740: mov 0,mem ! 741: dec r0,- ! 742: brz i_seq3 ! 743: /* ! 744: * if RLEN==0, interrupt RCV completion ! 745: */ ! 746: mov C_RLEN,brg ! 747: add brg,r10,mar ! 748: mov mem,r0|mar++ ! 749: or mem,r0 ! 750: dec r0,- ! 751: brc i_seq3 ! 752: mov SFULL,brg ! 753: or brg,r15 ! 754: i_seq3: ! 755: dec r15,- ! 756: brz i_seq6 ! 757: /* ! 758: * report RCV completion ! 759: */ ! 760: CHK1(B2_REP,2) ! 761: mov C_RLEN,brg ! 762: add brg,r10,mar ! 763: mov mem,r2 ! 764: mov 0,mem|mar++ ! 765: mov mem,r3 ! 766: mov 0,mem ! 767: mov %repinfo,%mar ! 768: mov repinfo,mar ! 769: mov KS_RDB,mem|mar++ ! 770: mov r2,mem|mar++ ! 771: mov r3,mem|mar++ ! 772: mov mem,mem|mar++ /* cntl char */ ! 773: mov r15,mem /* mode */ ! 774: CALL(report,s.report) ! 775: i_seq5: ! 776: mov r8,%mar ! 777: i_seq6: ! 778: /* ! 779: * if C_RQ, call 'rcv' (ignore char mode here) ! 780: */ ! 781: mov C_RQ,brg /* block mode */ ! 782: add brg,r10,mar ! 783: mov mem,brg ! 784: brz i_ebmode ! 785: mov %rcvsave,%mar ! 786: mov rcvsave,mar ! 787: mov r13,mem|mar++ ! 788: mov r12,mem ! 789: CALL(rcv,s.rcv) ! 790: mov rcvsave,mar ! 791: mov %rcvsave,%mar ! 792: mov mem,r13|mar++ ! 793: mov mem,r12 ! 794: i_ebmode: ! 795: /* ! 796: * TA0, TA1 = 0; ! 797: * C_RB = NIL; ! 798: * RBLEN == 0; ! 799: * only RLEN may be 0 to turn on the bit in r13 ! 800: */ ! 801: mov (1<<1),brg ! 802: and brg,r13 ! 803: mov r8,%mar ! 804: mov C_TA0,brg ! 805: add brg,r10,mar ! 806: mov 0,mem|mar++ ! 807: mov 0,mem ! 808: mov C_RBLEN,brg ! 809: add brg,r10,mar ! 810: mov 0,mem|mar++ ! 811: mov 0,mem|mar++ ! 812: mov NIL,mem ! 813: br i_loop ! 814: i_sq9.3: ! 815: /* ! 816: * char mode: put I_ECHO in RB ! 817: */ ! 818: mov I_ECHO,brg ! 819: or brg,r5,mem /* pseq */ ! 820: br i_loop ! 821: i_sq9.5: ! 822: /* ! 823: * C_RB was nil, now get a queue and put seq# in it ! 824: */ ! 825: GETQ(r2,i_noqb) ! 826: mov NIL,mem|mar++ /* pnext */ ! 827: mov 0,mem|mar++ /* plen */ ! 828: mov NIL,mem|mar++ /* pdata */ ! 829: mov I_ECHO,brg ! 830: or brg,r5,mem /* pseq */ ! 831: mov r8,%mar ! 832: mov C_RB,brg ! 833: add brg,r10,mar ! 834: mov r2,mem ! 835: br i_sq2.4 ! 836: i_nwwt: ! 837: /* ! 838: * rcv a not well formed trailer ! 839: * FREE C_RB and its buffer (*pdata) ! 840: * if TC0==BOTS RSEQ=r1&WINDOW; ! 841: * RSEQ is stored in r7 ! 842: */ ! 843: CHK1(B2_NWWT,2) ! 844: mov C_RB,brg ! 845: add brg,r10,mar ! 846: mov mem,r2 ! 847: brz i_nw3 ! 848: mov NIL,mem ! 849: CALL(clean,s.clean) ! 850: mov r8,%mar ! 851: i_nw3: ! 852: mov C_TA0,brg ! 853: add brg,r10,mar ! 854: mov mem,r0 ! 855: mov C_RSEQ,brg ! 856: add brg,r10,mar ! 857: mov I_BOTS,brg ! 858: addn brg,r0,- ! 859: brz 1f ! 860: mov I_REJ,brg ! 861: br 2f ! 862: 1: ! 863: mov r5,mem ! 864: mov I_ECHO,brg ! 865: 2: ! 866: mov mem,r1 ! 867: or brg,r1 ! 868: /* ! 869: * if (RULEN>0) { ! 870: * RADDR -= RULEN; RLEN += RULEN; RULEN = 0; ! 871: * } ! 872: */ ! 873: mov C_RULEN,brg ! 874: add brg,r10,mar ! 875: mov mem,r7 ! 876: mov 0,mem|mar++ ! 877: mov mem,r6|brg ! 878: mov 0,mem ! 879: or brg,r7,brg ! 880: mov brg,r0 ! 881: dec r0,- ! 882: brz i_nw6 ! 883: mov C_RLEN,brg ! 884: add brg,r10,mar ! 885: mov mem,r4 ! 886: mov r7,brg ! 887: add brg,r4,mem|mar++ ! 888: mov mem,r4 ! 889: mov r6,brg ! 890: addc brg,r4,mem|mar++ ! 891: mov mem,r4 ! 892: mov r7,brg ! 893: sub brg,r4,mem|mar++ /* RADDR */ ! 894: mov mem,r4 ! 895: mov r6,brg ! 896: subc brg,r4,mem|mar++ ! 897: mov mem,r4 ! 898: mov 0,brg ! 899: subc brg,r4,mem ! 900: /* ! 901: * turn off all bits in r13 except char mode (1<<6) bit ! 902: * if char mode, should not receive trailer at all ! 903: * hence, it is possible to mov brg,r13 here ! 904: */ ! 905: mov (1<<6),brg ! 906: and brg,r13 /* turn off all except bit 6 */ ! 907: /* ! 908: * if RQ is nil, send (REJ+RSEQ) : RSEQ in r1 ! 909: */ ! 910: mov C_RQ,brg ! 911: add brg,r10,mar ! 912: mov mem,brg ! 913: brz 1f ! 914: br i_nw6 ! 915: 1: ! 916: mov C_C,brg ! 917: add brg,r10,mar ! 918: mov r1,mem ! 919: CALL(send,s.send) ! 920: br i_ebmode ! 921: i_nw6: ! 922: /* ! 923: * RULEN==0 or RQ!=NIL ! 924: * put (REJ+RSEQ) in C_RQ ! 925: * r13 will adjusted in ebmode ! 926: */ ! 927: GETQ(r2,i_noqb) ! 928: mov NIL,mem|mar++ /* pnext */ ! 929: mov 0,mem|mar++ /* plen */ ! 930: mov NIL,mem|mar++ /* *pdata */ ! 931: mov r1,mem /* pseq (REJ+RSEQ) */ ! 932: mov r8,%mar ! 933: mov C_RQ,brg ! 934: add brg,r10,mar ! 935: 1: ! 936: mov mem,r0 ! 937: brz 2f ! 938: QA(r0) ! 939: br 1b ! 940: 2: ! 941: mov r2,mem ! 942: br i_ebmode ! 943: ! 944: i_data: ! 945: /* ! 946: * get a data byte: may be normal data, len, or express data in SOI ! 947: * r13: bit 7- rblen > 0 ! 948: * bit 6 - char mode ! 949: * bit 4- c_ta0 != 0 ! 950: * bit 1- rlen == 0 ! 951: * bit 0- raddr is odd ! 952: * r12: bit 0- 1st byte of a pair is in odl ! 953: * note that if odl has the 1st byte, rlen must be >= 2 ! 954: */ ! 955: dec r13,- ! 956: brc i_id4 /* special treatment */ ! 957: i_id1: ! 958: mov r12,brg ! 959: br0 i_id3 ! 960: /* ! 961: * test if rlen >= 2 ! 962: */ ! 963: mov r8,%mar ! 964: mov C_RLEN,brg ! 965: add brg,r10,mar ! 966: mov 2,r2|brg ! 967: mov mem,r3 ! 968: sub brg,r3,mem|mar++ ! 969: mov mem,r3 ! 970: mov 0,r0|brg ! 971: subc brg,r3,mem|mar++ /* mar points to RADDR */ ! 972: brc i_id2 /* rlen >= 2 */ ! 973: /* ! 974: * rlen <= 1 ! 975: */ ! 976: mov (1<<1),brg /* turn on no rcv pending */ ! 977: or brg,r13 ! 978: mov C_RLEN,brg ! 979: add brg,r10,mar ! 980: add mem,r2 ! 981: mov r2,mem|mar++ ! 982: mov 0,mem ! 983: dec r2,- ! 984: brz i_id8 /* RLEN == 0 */ ! 985: /* ! 986: * RLEN==1: copy one byte only ! 987: */ ! 988: br i_id5 ! 989: i_id2: ! 990: mov mem,oal /* RADDR */ ! 991: add mem,r2,mem|mar++ ! 992: mov mem,oah ! 993: addc mem,r0,mem|mar++ ! 994: mov mem,r11 ! 995: adc r11,mem|mar++ ! 996: add mem,r2,mem|mar++ /* RULEN */ ! 997: addc mem,r0,mem ! 998: mov (1<<0),brg ! 999: or brg,r12 ! 1000: mov r1,brg ! 1001: mov brg,odl ! 1002: br i_loop ! 1003: i_id3: ! 1004: /* ! 1005: * 2nd byte of a pair: put r1 in odh and copy them to RADDR ! 1006: * reset r12 ! 1007: */ ! 1008: mov ~(1<<0),brg ! 1009: and brg,r12 /* reset bit0 */ ! 1010: mov r1,brg ! 1011: mov brg,odh ! 1012: SPUTTWO(r11,err_bus) ! 1013: br i_loop ! 1014: i_id4: ! 1015: /* ! 1016: * r13 > 0 ! 1017: */ ! 1018: mov r13,brg ! 1019: br4 i_id10 /* c_ta0 != 0 */ ! 1020: br7 i_id8 /* rblen > 0 */ ! 1021: br1 i_id8 /* no read pending */ ! 1022: br0 i_id4.5 /* raddr is odd */ ! 1023: br i_id1 /* char mode */ ! 1024: i_id4.5: ! 1025: /* ! 1026: * raddr is odd ! 1027: * try to copy one byte first and make raddr even ! 1028: */ ! 1029: mov ~(1<<0),brg ! 1030: and brg,r13 ! 1031: i_id5: ! 1032: /* ! 1033: * enter here: copy r1 to raddr, since rlen, raddr, rulen were not updated, ! 1034: * now dec rlen and inc raddr and rulen ! 1035: */ ! 1036: mov r1,brg ! 1037: mov brg,odl ! 1038: mov brg,odh ! 1039: mov r8,%mar ! 1040: mov C_RLEN,brg ! 1041: add brg,r10,mar ! 1042: mov 1,r1 ! 1043: mov mem,r2 ! 1044: dec r2,mem|mar++ /* dec rlen */ ! 1045: mov mem,r2 ! 1046: mov 0,r0|brg ! 1047: mov brg,r12 /* reset r12 */ ! 1048: subc brg,r2,mem|mar++ ! 1049: mov mem,oal /* inc raddr */ ! 1050: add mem,r1,mem|mar++ ! 1051: mov mem,oah ! 1052: addc mem,r0,mem|mar++ ! 1053: mov mem,r2 ! 1054: addc mem,r0,mem|mar++ ! 1055: /* ! 1056: mov C_RULEN,brg ! 1057: add brg,r10,mar ! 1058: */ ! 1059: add mem,r1,mem|mar++ /* inc rulen */ ! 1060: addc mem,r0,mem ! 1061: SPUTONE(r2,err_bus) ! 1062: br i_loop ! 1063: i_id6: ! 1064: /* ! 1065: * no more data in DK rcv fifo, check if odl has the 1st byte ! 1066: */ ! 1067: mov r12,brg ! 1068: br0 1f ! 1069: br i_id7 ! 1070: 1: ! 1071: /* ! 1072: * odl has the 1st byte of a pair: copy it to RADDR then return ! 1073: * r13 needs adjusted ! 1074: */ ! 1075: CALL(copy1,s.copy1) ! 1076: i_id7: ! 1077: /* ! 1078: * if char mode and rulen>0, go check timer ! 1079: */ ! 1080: mov r8,%mar ! 1081: mov C_X1,brg ! 1082: add brg,r10,mar ! 1083: mov mem,r0 ! 1084: mov XBLK,brg ! 1085: orn brg,r0,- ! 1086: brz i_disp ! 1087: CALL(cktimer,s.cktimer) ! 1088: br i_disp ! 1089: i_id8: ! 1090: /* ! 1091: * rblen > 0 or no read pending ! 1092: */ ! 1093: mov 1,brg ! 1094: mov brg,idh /* indicate data byte */ ! 1095: i_id9: ! 1096: /* ! 1097: * copy data/cntl to C_RB ! 1098: */ ! 1099: mov (1<<7),brg ! 1100: or brg,r13 ! 1101: br i_nd ! 1102: i_id10: ! 1103: /* ! 1104: * c_ta0 != 0 ! 1105: */ ! 1106: mov r8,%mar ! 1107: mov C_TA1,brg ! 1108: add brg,r10,mar ! 1109: mov mem,r0 ! 1110: dec r0 ! 1111: brz 1f ! 1112: dec r0 ! 1113: brz 3f ! 1114: /* ! 1115: * TA1 (len) >=2; throw away the trailer (TA0); ! 1116: */ ! 1117: mov C_TA0,brg ! 1118: add brg,r10,mar ! 1119: mov 0,mem|mar++ ! 1120: mov 0,mem ! 1121: br 4f ! 1122: 1: ! 1123: /* ! 1124: * len was 0: TA2=r1, len=1;; ! 1125: */ ! 1126: mov 1,mem|mar++ /* TA1 = 1 */ ! 1127: mov r1,mem /* TA2 = r1 */ ! 1128: br i_loop ! 1129: 3: ! 1130: /* ! 1131: * len was 1: TA3=r1, len=2; ! 1132: */ ! 1133: mov 2,mem|mar++ /* TA1 = 2 */ ! 1134: mov mem,mem|mar++ ! 1135: mov r1,mem /* TA3 = r1 */ ! 1136: br i_loop ! 1137: 4: ! 1138: mov ~(1<<4),brg ! 1139: and brg,r13 /* reset c_ta0 bit */ ! 1140: br i_loop ! 1141: ! 1142: i_incomp: ! 1143: i_badp: ! 1144: /* ! 1145: * bad packet is received ! 1146: */ ! 1147: br i_csrtst ! 1148: /* ! 1149: * OLD code for i_badp ! 1150: * Check for the # of badpacks and possibly panic. ! 1151: mov %m_badpack,%mar ! 1152: mov m_badpack,mar ! 1153: mov mem,r0 ! 1154: inc r0,mem ! 1155: mov MAXBADPK,brg ! 1156: sub brg,r0 ! 1157: ERROR(E_IPANIC) ! 1158: br i_loop ! 1159: */ ! 1160: i_noqb: ! 1161: /* ! 1162: * Run out of queues or input buffers ! 1163: */ ! 1164: ERROR(E_NOQB) ! 1165: br i_disp ! 1166: i_disp: ! 1167: /* ! 1168: * Return to main dispatch loop ! 1169: */ ! 1170: mov %disp2,brg ! 1171: mov brg,pcr ! 1172: jmp disp2 ! 1173: ! 1174: i_nd: ! 1175: /* ! 1176: * copy data (r1) to stage-1 buffer (C_RB) ! 1177: * C_RB is a queue pointer: pnext, plen, *pdata, pseq. ! 1178: * idh - 1 if normal data, 0 if user cntl ! 1179: * r7-r5 - buffer address ! 1180: * r4 - stage-1 buffer index ! 1181: * r3 - plen ! 1182: * r2 - queue entry ! 1183: * r1 - data byte ! 1184: */ ! 1185: CHK(B2_DATA,2) ! 1186: mov r8,%mar ! 1187: mov C_RBLEN,brg ! 1188: add brg,r10,mar ! 1189: mov mem,r0 ! 1190: inc r0,mem|mar++ ! 1191: mov mem,r0 ! 1192: adc r0,mem|mar++ /* RBLEN++ */ ! 1193: mov mem,r0 /* r0 = C_RB */ ! 1194: brz i_nd5 ! 1195: i_nd1: ! 1196: mov r0,odl /* save temporarily in odl */ ! 1197: QA(r0) ! 1198: mov mem,r0|mar++ ! 1199: brz i_nd2 ! 1200: br i_nd1 ! 1201: i_nd2: ! 1202: /* ! 1203: * found end of the queue ! 1204: */ ! 1205: mov mem,r3|mar++ /* plen */ ! 1206: mov mem,r4|mar++ /* *pdata */ ! 1207: mov mem,r0 /* pseq */ ! 1208: dec r0,- ! 1209: brc i_nd7 /* get a new queue */ ! 1210: mov BSIZE,brg ! 1211: sub brg,r3,- ! 1212: brc i_nd7 /* this buffer is full */ ! 1213: mov odl,r0 ! 1214: QA(r0) ! 1215: mov brg,brg|mar++ /* pnext */ ! 1216: inc r3,mem|mar++ /* plen++ */ ! 1217: i_nd3: ! 1218: /* ! 1219: * r4 is buffer index, store 2 bytes (lo in r1 , hi in odh) ! 1220: */ ! 1221: BITA(r4,r7,r6,r5) ! 1222: asl r3,brg /* offset is 2*plen */ ! 1223: add brg,r7,r7|brg ! 1224: mov brg,oal ! 1225: adc r6,r6|brg ! 1226: mov brg,oah ! 1227: adc r5 ! 1228: mov r1,brg ! 1229: mov brg,odl ! 1230: mov idh,odh ! 1231: SPUTTWO(r5,err_bus) /* always at even boundary */ ! 1232: br i_loop ! 1233: i_nd5: ! 1234: /* ! 1235: * no stage-1 buffer exists yet ! 1236: */ ! 1237: GETQ(r2,i_noqb) ! 1238: mov r8,%mar ! 1239: mov C_RB,brg ! 1240: add brg,r10,mar ! 1241: mov r2,mem ! 1242: i_nd6: ! 1243: /* ! 1244: * get a buffer and store 2 bytes at offset plen ! 1245: */ ! 1246: GEBI(r4,i_noqb) ! 1247: QA(r2) ! 1248: mov NIL,mem|mar++ ! 1249: mov 1,mem|mar++ /* plen after storing */ ! 1250: mov r4,mem|mar++ /* *pdata */ ! 1251: mov 0,mem /* pseq */ ! 1252: mov mem,r3 /* plen before storing */ ! 1253: br i_nd3 ! 1254: i_nd7: ! 1255: /* ! 1256: * get another queue and buffer to store 2 bytes ! 1257: */ ! 1258: GETQ(r2,i_noqb) ! 1259: mov odl,r0 ! 1260: QA(r0) ! 1261: mov r2,mem ! 1262: br i_nd6 ! 1263: ! 1264: endseg2: ! 1265: ! 1266:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.