|
|
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.