V8/usr/sys/kdi/input.s
/*
* 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: