/* * Input Segment */ .org 2048 seg2: in: CHK(B2_ENT,2) /* check point */ SENDCMD(D_READ) /* for dr11-c version */ i_csrtst: /* * While there is data in the receiver fifo * copy it out * While (dkcsr & DKRDONE) { */ READDATA(i_disp) /* * Scan for the 1st word of a packet where a channel # * in the low byte and DKMARK in the hi byte * If not the packet marker, just throw it away and repeat */ mov ILO,r9 /* read chan # */ mov IHI,brg /* read hi byte and strobe */ br1 i_mark DELAY(3) br i_csrtst i_mk4: /* * a data in odl left over from last chan# (r9) */ CALL(copy1,s.copy1) br i_mk7 i_mk5: /* * for char mode, check for timeout */ CALL(cktimer,s.cktimer) br i_mk8 i_mk6: /* * see a DKMARK again * r13 and r12 can't be destroyed elsewhere e.g. 'rcv' */ mov r1,brg addn brg,r9,- brz i_lp0 mov r12,brg br0 i_mk4 /* copy the left-over byte in odl */ i_mk7: /* * if the previous channel was in char mode and timeout mode, * then do timeout processing */ asl r13,brg br7 i_mk5 /* char mode */ i_mk8: mov r1,brg mov brg,r9 i_mark: /* * We found the 1st word, the channel # is in r9 * If the channel # is 377 (all 1's), that means * probably power failed or module fell out of bin */ dec r9,- brz i_incomp mov CHANMODS,brg sub brg,r9,- /* chan# - CHANMODS */ brc i_incomp GLTE(r9) /* set up r8/r10 */ /* * r13: a global flag in input.s * bit 7 - RBLEN > 0 (or C_RB != NULL) * bit 6 - char mode * bit 4 - C_TA0 != 0 * bit 1 - RLEN == 0 * bit 0 - RADDR is odd * r12: a global flag in input.s * bit 0 - odl has the 1st byte of a pair * r15: report mode */ mov 0,brg mov brg,r13 mov brg,r12 mov C_RB,brg add brg,r10,mar mov mem,brg brz 1f mov (1<<7),brg or brg,r13 1: mov C_X1,brg add brg,r10,mar mov mem,r0 mov XBLK,brg orn brg,r0,- brz 1f mov (1<<6),brg or brg,r13 1: mov C_TA0,brg add brg,r10,mar mov mem,r0 dec r0,- brz 1f mov (1<<4),brg or brg,r13 1: mov C_RLEN,brg add brg,r10,mar mov mem,r0|mar++ or mem,r0,r0|mar++ dec r0,- brc 1f mov (1<<1),brg or brg,r13 1: mov mem,brg br0 1f br i_loop 1: mov (1<<0),brg or brg,r13 i_lp0: /* * add possible delay for null byte */ DELAY(0) D422(1) i_loop: /* * main loop to read the rest of the packet * see if a control envelop or data envelop */ D422(0) READDATA(i_id6) mov ILO,r1 mov IHI,brg br1 i_mk6 /* see DKMARK again */ br0 i_data /* * A good control envelop is detected for chan # (in r9) * control data in r1 * if 1 <= r1 <= 010, interface module cntl * if 010 <= r1 <= 077, protocol cntl * if 0100 <= r1 <= 0177, user cntl * if r1 >= 0200, supervision cntl */ dec r1,- brz i_lp0 /* null byte */ CHK(B2_CNTL,2) /* check point */ /* * if r12.0 call copy1, adjust r13 */ mov r12,brg br0 i_lp4 i_lp2: mov r1,brg br7 i_tdkcl mov 0277,brg /* 6-th bit is not set */ or brg,r1,brg brz i_ucntl /* * this is a protocol cntl char * r5 = r1 & WINDOW * r0 = r1 & 0370 */ mov 0370,brg and brg,r1,brg mov brg,r0 mov WINDOW,brg and brg,r1,brg mov brg,r5 /* * switch (r0) { * case ..... */ mov I_SEQ,brg addn brg,r0,- brz i_seq mov I_ECHO,brg addn brg,r0,- brz i_echo mov I_ACK,brg addn brg,r0,- brz i_ack mov I_BOT,brg addn brg,r0,- brz i_050 mov I_REJ,brg addn brg,r0,- brz i_rej mov I_AINIT,brg addn brg,r1,- brz i_ainit mov I_INIT1,brg addn brg,r1,- brz i_init mov I_INIT0,brg addn brg,r1,- brz i_init i_umeta: /* * un-recognized meta char */ /* ERROR(E_UMETA) */ br i_loop i_tdkcl: /* * code overflow to output.s */ mov %ii_tdkcl,brg mov brg,pcr jmp ii_tdkcl i_ucntl: /* * rcv a user cntl char * if (r12.0) then copy odl to raddr first * set idh to 0 and goto id9 */ CHK1(B2_SUP,2) mov 0,brg mov brg,idh /* indicate cntl */ br i_id9 /* copy to C_RB */ i_lp4: CALL(copy1,s.copy1) br i_lp2 i_050: mov sw050,brg br (add,brg,r5),%sw050 sw050: br i_bot br i_botm br i_bots br i_soi br i_eoi br i_enq br i_check br i_initreq i_init: /* * code overflow to output.s */ mov %ii_init,brg mov brg,pcr jmp ii_init i_ainit: /* * code overflow to output.s */ mov %ii_ainit,brg mov brg,pcr jmp ii_ainit i_initreq: /* * code overflow to output.s */ mov %ii_req,brg mov brg,pcr jmp ii_req i_enq: /* * code overflow to output.s */ mov %ii_enq,brg mov brg,pcr jmp ii_enq i_check: /* * code overflow to output.s */ mov %ii_check,brg mov brg,pcr jmp ii_check i_bot: i_botm: i_bots: i_soi: /* * TA0 = r1; TA1 = 0; */ CHK(B4_BOT,4) mov r8,%mar mov C_TA0,brg add brg,r10,mar mov r1,mem|mar++ mov 0,mem mov (1<<4),brg or brg,r13 br i_loop i_eoi: /* * code overflow to output.s */ mov %ii_eoi,brg mov brg,pcr jmp ii_eoi i_rej: /* * if XENQ is set, then treat this REJ as ECHO * otherwise ignore this REJ */ mov r8,%mar mov C_X1,brg add brg,r10,mar mov mem,r0 mov ~XENQ,brg or brg,r0,- brz i_ec0 /* XENQ is set, no ECHO was rcv */ br i_loop /* ignore this REJ */ i_echo: /* * R = r5; * if ((S-R-1)&07 < (S-A-1)&07) { * len1 = r5 - A; * X &= ~XREJ; A = r5; * if (len1==0) goto i_rej1; * len2 = (len1)*DKBLOCK; * ...... * } */ CHK(B3_ECHO,3) mov r8,%mar mov C_X1,brg add brg,r10,mar mov mem,r0 mov ~XENQ,brg i_ec0: and brg,r0,mem /* reset XENQ */ mov C_S,brg add brg,r10,mar mov mem,r3 mov mem,r4|mar++ /* r4, r3 = S */ mov r5,mem /* R = r5 */ addn mem,r4,r4|mar++ /* r4 = S-R-1 */ addn mem,r3 /* r3 = S-A-1 */ mov WINDOW,brg and brg,r4 and brg,r3,brg sub brg,r4,- brc i_rej1 /* (S-R-1) >= (S-A-1) */ i_gack: mov mem,r2 /* r2 = old A */ mov r5,mem /* A = r5 */ mov C_X1,brg add brg,r10,mar mov mem,r0 mov ~XREJ,brg and brg,r0,mem /* X &= ~XREJ */ /* * if XLEN==0 and XCNTL==0, xmit is inactive, discard this ECHO/REJ */ mov C_XLEN,brg add brg,r10,mar mov mem,r0|mar++ or mem,r0 dec r0,- brc 1f mov C_XCNTL,brg add brg,r10,mar mov mem,r0 dec r0,- brz i_xnil /* check if trailer only mode */ 1: mov r2,brg sub brg,r1,brg mov brg,r2 /* r2 = r1 - old A */ mov WINDOW,brg and brg,r2 /* r2 = len1 */ dec r2,- brz i_rej1 mov DKBLOCK,brg mov brg,r3 TIMES(r2,r3,r7,r6) /* r7/6 (len2) = r2 * r3 */ /* * if (len2>XLEN) { XLEN=0; report; } * else if (len2=XLEN) { XLEN=0; report if ~XCNTL; } * else if (len2<XLEN) { XLEN -= len2; XADDR =+ len2; } */ mov C_XLEN,brg add brg,r10,mar mov mem,r3 mov r6,brg sub brg,r3,mem mov mem,r0|mar++ mov mem,r4 mov r7,brg subc brg,r4,mem brc i_ec2 /* XLEN >= len2 */ i_ec1: /* * This chan has done the transmission * remove chan# from 'outq' and report */ mov C_XLEN,brg add brg,r10,mar mov 0,mem|mar++ mov 0,mem mov C_XCNTL,brg add brg,r10,mar mov 0,mem mov %repinfo,%mar mov repinfo,mar mov KS_SEND,mem CALL(report,s.report) /* * remove chan# from 'outq' * r2: running ptr of outq, r3: next ptr in outq, r4: ptr of outq1 */ mov outq,mar mov %outq,%mar mov mem,r2 0: brz 6f QA(r2) mov mem,r3 mov NIL,mem|mar++ addn mem,r9,- brz 5f mov outq1,mar mov %outq1,%mar 1: mov mem,r4 brz 2f QA(r4) br 1b 2: /* put r2 at the end of outq1 */ mov r2,mem 3: /* put r3 to r2 */ mov r3,brg mov brg,r2 br 0b 5: /* delete this chan# */ FREEQ(r2) br 3b 6: /* restore outq from outq1 */ mov outq1,mar mov %outq1,%mar mov mem,brg mov outq,mar mov %outq,%mar mov brg,mem|mar++ mov NIL,mem mov r8,%mar br i_rej1 i_ec2: /* * len2 <= XLEN */ or mem,r0,r0|mar++ dec r0,- brc i_ec3 /* len2 < XLEN */ /* * len2 = XLEN: check if XCNTL is user cntl */ mov C_XCNTL,brg add brg,r10,mar mov mem,r0 mov 0300,brg and brg,r0 mov 0100,brg addn brg,r0,- brz i_rej1 /* don't report */ br i_ec1 i_ec3: /* * len2 < XLEN * C_XADDR += len2; */ mov 0,r0 add mem,r6,mem|mar++ addc mem,r7,mem|mar++ addc mem,r0,mem i_rej1: /* * if REJ && (X&XREJ==0) */ mov ~I_REJ,brg or brg,r1,brg brz 1f br i_loop 1: mov C_X1,brg add brg,r10,mar mov mem,r0 mov ~XREJ,brg or brg,r0,- brz i_loop /* if REJ had been rcv, ignore this REJ */ i_grej: /* * rcv a REJ: S=(r5+1)&WINDOW, X |= XREJ; */ CHK1(B3_REJ,3) inc r5 mov C_S,brg add brg,r10,mar mov WINDOW,brg and brg,r5,mem mov C_X1,brg add brg,r10,mar mov XREJ,brg mov brg,r0 or mem,r0,mem /* * if XNIL, call strailer, else loop */ mov ~XNIL,brg or brg,r0,- brz 1f br i_loop 1: CALL(strailer,s.strailer) br i_loop i_xnil: /* * if XNIL, report completion, else loop */ mov C_X1,brg add brg,r10,mar mov mem,r0 mov XNIL,brg orn brg,r0,- brz 1f br i_loop /* rcv suspicious ECHO */ 1: xor brg,r0,mem /* reset XNIL bit */ br i_ec1 /* report KS_SEND */ i_ack: /* * if (r5!=A) goto i_gack; * if ((X&XREJ) == 0)) goto i_grej; * break; */ CHK(B3_ACK,3) mov r8,%mar mov C_X1,brg add brg,r10,mar mov mem,r4 mov ~XACK,brg and brg,r4,mem mov C_A,brg add brg,r10,mar addn mem,r5,- brz 1f br i_gack 1: mov (XREJ|XACK),brg and brg,r4 dec r4,- brz i_grej br i_loop i_seq: /* * pseq = ECHO + r5; * check if char or block mode processing * r13.6 == 0 block mode, else char mode */ CHK(B3_SEQ,3) mov 0,brg mov brg,r15 /* report mode */ mov r8,%mar asl r13,brg /* bit 6 of r13 is char mode */ br7 i_seq2 /* * BLOCK mode: * check if trailer is well formed and len is correct: */ mov C_TA0,brg add brg,r10,mar mov mem,r7|mar++ mov mem,r6|mar++ dec r7,- brz i_nwwt mov I_SOI,brg addn brg,r7,- brz i_nwwt mov 2,brg addn brg,r6,- brz 1f br i_nwwt 1: mov mem,r0|mar++ /* TA2 */ mov mem,r6 /* TA3 */ mov C_RBLEN,brg add brg,r10,mar mov mem,r3|mar++ mov mem,r2 mov C_RULEN,brg add brg,r10,mar add mem,r3,brg|mar++ addc mem,r2 sub brg,r0 mov r2,brg subc brg,r6,brg or brg,r0 dec r0,- brc i_nwwt mov C_RSEQ,brg add brg,r10,mar mov mem,r0 inc r0 mov WINDOW,brg and brg,r0,brg addn brg,r5,- brz i_sq2.1 br i_nwwt i_seq2: /* * has rcv a good block * C_RSEQ = r5; */ mov C_RSEQ,brg add brg,r10,mar i_sq2.1: mov r5,mem /* * if (RB==NIL & RQ==NIL & (RLEN!=0 | RULEN!=0)), echo the seq# now */ mov C_RQ,brg add brg,r10,mar mov mem,r2 mov C_RB,brg add brg,r10,mar and mem,r2 brz 1f br i_sq2.3 1: mov C_RLEN,brg add brg,r10,mar mov mem,r2|mar++ or mem,r2 mov C_RULEN,brg add brg,r10,mar or mem,r2,r2|mar++ or mem,r2 dec r2,- brz i_sq2.2 mov I_ECHO,brg or brg,r5,brg mov brg,r1 CALL(send,s.send) mov r8,%mar mov C_C,brg add brg,r10,mar mov r1,mem asl r13,brg br7 i_loop /* go if char mode */ /* * if TA0 (r7) != BOTM, interrupt with SBLOCK */ mov I_BOTM,brg addn brg,r7,- brz i_sq2.8 /* * see if YBLOCK is set */ mov C_Y,brg add brg,r10,mar mov mem,r0 mov YBLOCK,brg orn brg,r0,- brz 1f br i_sq2.8 1: /* * interrupt RCV completion with SBLOCK */ mov SBLOCK,brg or brg,r15 br i_sq2.8 i_sq2.2: mov C_RB,brg add brg,r10,mar i_sq2.3: /* * put seq# at the end of C_RB * mar/%mar now points to C_RB */ mov mem,r2 brz i_sq9.5 i_sq2.4: /* * block mode if r13.6==0 * at least part of the data is in stage-1 (RB: r2) buffer * if TA0 (r7) != BOTM, pseq = I_SEQ + r5 */ mov mem,r3 1: QA(r3) mov mem,r3|mar++ brz 2f br 1b 2: mov mem,mem|mar++ /* plen */ mov mem,mem|mar++ /* *pdata */ asl r13,brg br7 i_sq9.3 /* char mode */ /* * block mode */ mov I_BOTM,brg addn brg,r7,- brz 1f mov I_SEQ,mem br 2f 1: mov I_ECHO,mem 2: or mem,r5,mem /* pseq */ /* * put this queue (r2) to end of C_RQ */ mov r8,%mar mov C_RQ,brg add brg,r10,mar 1: mov mem,r0 brz 2f QA(r0) br 1b 2: mov r2,mem mov r8,%mar i_sq2.8: /* * if RULEN==0, no data have been copied to RADDR */ mov C_RULEN,brg add brg,r10,mar mov mem,r0 mov 0,mem|mar++ or mem,r0 mov 0,mem dec r0,- brz i_seq3 /* * if RLEN==0, interrupt RCV completion */ mov C_RLEN,brg add brg,r10,mar mov mem,r0|mar++ or mem,r0 dec r0,- brc i_seq3 mov SFULL,brg or brg,r15 i_seq3: dec r15,- brz i_seq6 /* * report RCV completion */ CHK1(B2_REP,2) mov C_RLEN,brg add brg,r10,mar mov mem,r2 mov 0,mem|mar++ mov mem,r3 mov 0,mem mov %repinfo,%mar mov repinfo,mar mov KS_RDB,mem|mar++ mov r2,mem|mar++ mov r3,mem|mar++ mov mem,mem|mar++ /* cntl char */ mov r15,mem /* mode */ CALL(report,s.report) i_seq5: mov r8,%mar i_seq6: /* * if C_RQ, call 'rcv' (ignore char mode here) */ mov C_RQ,brg /* block mode */ add brg,r10,mar mov mem,brg brz i_ebmode mov %rcvsave,%mar mov rcvsave,mar mov r13,mem|mar++ mov r12,mem CALL(rcv,s.rcv) mov rcvsave,mar mov %rcvsave,%mar mov mem,r13|mar++ mov mem,r12 i_ebmode: /* * TA0, TA1 = 0; * C_RB = NIL; * RBLEN == 0; * only RLEN may be 0 to turn on the bit in r13 */ mov (1<<1),brg and brg,r13 mov r8,%mar mov C_TA0,brg add brg,r10,mar mov 0,mem|mar++ mov 0,mem mov C_RBLEN,brg add brg,r10,mar mov 0,mem|mar++ mov 0,mem|mar++ mov NIL,mem br i_loop i_sq9.3: /* * char mode: put I_ECHO in RB */ mov I_ECHO,brg or brg,r5,mem /* pseq */ br i_loop i_sq9.5: /* * C_RB was nil, now get a queue and put seq# in it */ GETQ(r2,i_noqb) mov NIL,mem|mar++ /* pnext */ mov 0,mem|mar++ /* plen */ mov NIL,mem|mar++ /* pdata */ mov I_ECHO,brg or brg,r5,mem /* pseq */ mov r8,%mar mov C_RB,brg add brg,r10,mar mov r2,mem br i_sq2.4 i_nwwt: /* * rcv a not well formed trailer * FREE C_RB and its buffer (*pdata) * if TC0==BOTS RSEQ=r1&WINDOW; * RSEQ is stored in r7 */ CHK1(B2_NWWT,2) mov C_RB,brg add brg,r10,mar mov mem,r2 brz i_nw3 mov NIL,mem CALL(clean,s.clean) mov r8,%mar i_nw3: mov C_TA0,brg add brg,r10,mar mov mem,r0 mov C_RSEQ,brg add brg,r10,mar mov I_BOTS,brg addn brg,r0,- brz 1f mov I_REJ,brg br 2f 1: mov r5,mem mov I_ECHO,brg 2: mov mem,r1 or brg,r1 /* * if (RULEN>0) { * RADDR -= RULEN; RLEN += RULEN; RULEN = 0; * } */ mov C_RULEN,brg add brg,r10,mar mov mem,r7 mov 0,mem|mar++ mov mem,r6|brg mov 0,mem or brg,r7,brg mov brg,r0 dec r0,- brz i_nw6 mov C_RLEN,brg add brg,r10,mar mov mem,r4 mov r7,brg add brg,r4,mem|mar++ mov mem,r4 mov r6,brg addc brg,r4,mem|mar++ mov mem,r4 mov r7,brg sub brg,r4,mem|mar++ /* RADDR */ mov mem,r4 mov r6,brg subc brg,r4,mem|mar++ mov mem,r4 mov 0,brg subc brg,r4,mem /* * turn off all bits in r13 except char mode (1<<6) bit * if char mode, should not receive trailer at all * hence, it is possible to mov brg,r13 here */ mov (1<<6),brg and brg,r13 /* turn off all except bit 6 */ /* * if RQ is nil, send (REJ+RSEQ) : RSEQ in r1 */ mov C_RQ,brg add brg,r10,mar mov mem,brg brz 1f br i_nw6 1: mov C_C,brg add brg,r10,mar mov r1,mem CALL(send,s.send) br i_ebmode i_nw6: /* * RULEN==0 or RQ!=NIL * put (REJ+RSEQ) in C_RQ * r13 will adjusted in ebmode */ GETQ(r2,i_noqb) mov NIL,mem|mar++ /* pnext */ mov 0,mem|mar++ /* plen */ mov NIL,mem|mar++ /* *pdata */ mov r1,mem /* pseq (REJ+RSEQ) */ mov r8,%mar mov C_RQ,brg add brg,r10,mar 1: mov mem,r0 brz 2f QA(r0) br 1b 2: mov r2,mem br i_ebmode i_data: /* * get a data byte: may be normal data, len, or express data in SOI * r13: bit 7- rblen > 0 * bit 6 - char mode * bit 4- c_ta0 != 0 * bit 1- rlen == 0 * bit 0- raddr is odd * r12: bit 0- 1st byte of a pair is in odl * note that if odl has the 1st byte, rlen must be >= 2 */ dec r13,- brc i_id4 /* special treatment */ i_id1: mov r12,brg br0 i_id3 /* * test if rlen >= 2 */ mov r8,%mar mov C_RLEN,brg add brg,r10,mar mov 2,r2|brg mov mem,r3 sub brg,r3,mem|mar++ mov mem,r3 mov 0,r0|brg subc brg,r3,mem|mar++ /* mar points to RADDR */ brc i_id2 /* rlen >= 2 */ /* * rlen <= 1 */ mov (1<<1),brg /* turn on no rcv pending */ or brg,r13 mov C_RLEN,brg add brg,r10,mar add mem,r2 mov r2,mem|mar++ mov 0,mem dec r2,- brz i_id8 /* RLEN == 0 */ /* * RLEN==1: copy one byte only */ br i_id5 i_id2: mov mem,oal /* RADDR */ add mem,r2,mem|mar++ mov mem,oah addc mem,r0,mem|mar++ mov mem,r11 adc r11,mem|mar++ add mem,r2,mem|mar++ /* RULEN */ addc mem,r0,mem mov (1<<0),brg or brg,r12 mov r1,brg mov brg,odl br i_loop i_id3: /* * 2nd byte of a pair: put r1 in odh and copy them to RADDR * reset r12 */ mov ~(1<<0),brg and brg,r12 /* reset bit0 */ mov r1,brg mov brg,odh SPUTTWO(r11,err_bus) br i_loop i_id4: /* * r13 > 0 */ mov r13,brg br4 i_id10 /* c_ta0 != 0 */ br7 i_id8 /* rblen > 0 */ br1 i_id8 /* no read pending */ br0 i_id4.5 /* raddr is odd */ br i_id1 /* char mode */ i_id4.5: /* * raddr is odd * try to copy one byte first and make raddr even */ mov ~(1<<0),brg and brg,r13 i_id5: /* * enter here: copy r1 to raddr, since rlen, raddr, rulen were not updated, * now dec rlen and inc raddr and rulen */ mov r1,brg mov brg,odl mov brg,odh mov r8,%mar mov C_RLEN,brg add brg,r10,mar mov 1,r1 mov mem,r2 dec r2,mem|mar++ /* dec rlen */ mov mem,r2 mov 0,r0|brg mov brg,r12 /* reset r12 */ subc brg,r2,mem|mar++ mov mem,oal /* inc raddr */ add mem,r1,mem|mar++ mov mem,oah addc mem,r0,mem|mar++ mov mem,r2 addc mem,r0,mem|mar++ /* mov C_RULEN,brg add brg,r10,mar */ add mem,r1,mem|mar++ /* inc rulen */ addc mem,r0,mem SPUTONE(r2,err_bus) br i_loop i_id6: /* * no more data in DK rcv fifo, check if odl has the 1st byte */ mov r12,brg br0 1f br i_id7 1: /* * odl has the 1st byte of a pair: copy it to RADDR then return * r13 needs adjusted */ CALL(copy1,s.copy1) i_id7: /* * if char mode and rulen>0, go check timer */ mov r8,%mar mov C_X1,brg add brg,r10,mar mov mem,r0 mov XBLK,brg orn brg,r0,- brz i_disp CALL(cktimer,s.cktimer) br i_disp i_id8: /* * rblen > 0 or no read pending */ mov 1,brg mov brg,idh /* indicate data byte */ i_id9: /* * copy data/cntl to C_RB */ mov (1<<7),brg or brg,r13 br i_nd i_id10: /* * c_ta0 != 0 */ mov r8,%mar mov C_TA1,brg add brg,r10,mar mov mem,r0 dec r0 brz 1f dec r0 brz 3f /* * TA1 (len) >=2; throw away the trailer (TA0); */ mov C_TA0,brg add brg,r10,mar mov 0,mem|mar++ mov 0,mem br 4f 1: /* * len was 0: TA2=r1, len=1;; */ mov 1,mem|mar++ /* TA1 = 1 */ mov r1,mem /* TA2 = r1 */ br i_loop 3: /* * len was 1: TA3=r1, len=2; */ mov 2,mem|mar++ /* TA1 = 2 */ mov mem,mem|mar++ mov r1,mem /* TA3 = r1 */ br i_loop 4: mov ~(1<<4),brg and brg,r13 /* reset c_ta0 bit */ br i_loop i_incomp: i_badp: /* * bad packet is received */ br i_csrtst /* * OLD code for i_badp * Check for the # of badpacks and possibly panic. mov %m_badpack,%mar mov m_badpack,mar mov mem,r0 inc r0,mem mov MAXBADPK,brg sub brg,r0 ERROR(E_IPANIC) br i_loop */ i_noqb: /* * Run out of queues or input buffers */ ERROR(E_NOQB) br i_disp i_disp: /* * Return to main dispatch loop */ mov %disp2,brg mov brg,pcr jmp disp2 i_nd: /* * copy data (r1) to stage-1 buffer (C_RB) * C_RB is a queue pointer: pnext, plen, *pdata, pseq. * idh - 1 if normal data, 0 if user cntl * r7-r5 - buffer address * r4 - stage-1 buffer index * r3 - plen * r2 - queue entry * r1 - data byte */ CHK(B2_DATA,2) mov r8,%mar mov C_RBLEN,brg add brg,r10,mar mov mem,r0 inc r0,mem|mar++ mov mem,r0 adc r0,mem|mar++ /* RBLEN++ */ mov mem,r0 /* r0 = C_RB */ brz i_nd5 i_nd1: mov r0,odl /* save temporarily in odl */ QA(r0) mov mem,r0|mar++ brz i_nd2 br i_nd1 i_nd2: /* * found end of the queue */ mov mem,r3|mar++ /* plen */ mov mem,r4|mar++ /* *pdata */ mov mem,r0 /* pseq */ dec r0,- brc i_nd7 /* get a new queue */ mov BSIZE,brg sub brg,r3,- brc i_nd7 /* this buffer is full */ mov odl,r0 QA(r0) mov brg,brg|mar++ /* pnext */ inc r3,mem|mar++ /* plen++ */ i_nd3: /* * r4 is buffer index, store 2 bytes (lo in r1 , hi in odh) */ BITA(r4,r7,r6,r5) asl r3,brg /* offset is 2*plen */ add brg,r7,r7|brg mov brg,oal adc r6,r6|brg mov brg,oah adc r5 mov r1,brg mov brg,odl mov idh,odh SPUTTWO(r5,err_bus) /* always at even boundary */ br i_loop i_nd5: /* * no stage-1 buffer exists yet */ GETQ(r2,i_noqb) mov r8,%mar mov C_RB,brg add brg,r10,mar mov r2,mem i_nd6: /* * get a buffer and store 2 bytes at offset plen */ GEBI(r4,i_noqb) QA(r2) mov NIL,mem|mar++ mov 1,mem|mar++ /* plen after storing */ mov r4,mem|mar++ /* *pdata */ mov 0,mem /* pseq */ mov mem,r3 /* plen before storing */ br i_nd3 i_nd7: /* * get another queue and buffer to store 2 bytes */ GETQ(r2,i_noqb) mov odl,r0 QA(r0) mov r2,mem br i_nd6 endseg2: