V8/usr/sys/kdi/output.s

Compare this file to the similar file:
Show the results in this format:


/*
 * Output segment
 */
	.org	1024
seg1:
charsw:
/*	br	o_isbs		/* 010 - BS */
/*	br	o_isht		/* 011 - HT */
/*	br	o_isnl		/* 012 - NL */
/*	br	o_isvt		/* 013 - VT */
/*	br	o_isff		/* 014 - FF */
/*	br	o_iscr		/* 015 - CR */
/*	br	o_sendit	/* 016 - SO */
/*	br	o_sendit	/* 017 - SI */

out:
/*
 * This is equivalent to xmit routine
 */
	CHK(B1_ENT,1)		/* check point */
/*
 * Registers are used as follows:
 *	r15 - flag
 *	r14 - free queue pointer
 *	r13 - bit 7-0 of XADDR
 *	r12 - bit 15-8 of XADDR
 *	r11 - bit 17-16 of XADDR
 *	r9 - chan#
 *	r8/r10 - LTE address
 *	r7 - blklen, pklen
 *	r6,r5 - XLEN
 *	r4 - C_S
 * 	r3 - C_R
 *	r2 - blklen
 *
 */

/*
 * outq is a linked list for all output active channels
 */
	CHK(B1_ERO,1)		/* check point */
	mov	outq,mar
	mov	%outq,%mar
	mov	mem,r2|mar++	/* outq1 = outq */
	mov	r2,mem
o_robin:
/*
 * while (outq1) (pointer in r2)
 */
	brz	o_bye
	QA(r2)
	mov	mem,r2|mar++
	mov	mem,r9
	mov	outq1,mar
	mov	%outq1,%mar
	mov	r2,mem
	GLTE(r9)		/* set up r8/r10 */
/*
 * if (C_S ^ C_R)&DKBMASK), then the chan is blocked
 */
	mov	C_S,brg
	add	brg,r10,mar
	mov	mem,r4|mar++
	xor	mem,r4,brg
	mov	brg,r0
	mov	DKBMASK,brg
	and	brg,r0
	dec	r0,-
	brz	o_endrobin
	mov	mem,r3|mar++
	mov	mem,r2			/* r2 = C_A */
/*
 * r15 is a flag:
 *	bit 0 - C_S == C_R
 *	bit 1 - mlen == 0
 *	bit 4 - send XCNTL
 */
	mov	C_XCNTL,brg
	add	brg,r10,mar
	mov	mem,r0
	dec	r0,-
	brz	1f
	mov	(1<<4),brg
	br	2f
1:	mov	0,brg
2:	mov	brg,r15
/*
 * mlen' (in r1/r2) = (S-A-1)&07 * DKBLOCK
 */
	mov	r2,brg
	addn	brg,r4,brg		/* brg=C_S-C_A-1 */
	mov	brg,r5
	mov	WINDOW,brg
	and	brg,r5
	mov	DKBLOCK,brg
	mov	brg,r6
	TIMES(r5,r6,r2,r1)
/*
 * if (mlen'<XLEN) {mlen=XLEN-mlen'; goto o_while;}
 * else if (mlen'>XLEN) { goto o_endrobin; }
 * else if (mlen'=XLEN) { goto o_cntl; }
 *
 * mlen (r6/5) = XLEN (r6/5) - mlen' (r1/r2)
 */
	mov	C_XLEN,brg
	add	brg,r10,mar
	mov	mem,r6|mar++
	mov	mem,r5|mar++
	mov	r1,brg
	sub	brg,r6
	mov	r2,brg
	subc	brg,r5,r5|brg
	brc	1f
/*
 * XLEN < mlen': no data to go out
 */
	br	o_endrobin
1:
/*
 * see if mlen==0
 */
	or	brg,r6,brg
	mov	brg,r0
	dec	r0,-
	brz	o_cntl		/* send XCNTL, if any */
/*
 * ptr = C_XADDR+mlen'
 */
	add	mem,r1,brg|mar++
	mov	brg,r13
	addc	mem,r2,brg|mar++
	mov	brg,r12
	mov	mem,r11
	adc	r11
o_while:
/*
 * blklen (in r2) = min{mlen, DKBLOCK}
 * mlen -= blklen
 */
	mov	DKBLOCK+1,brg
	sub	brg,r6
	mov	0,brg
	subc	brg,r5
	brc	o_chunk
/*
 * mlen <= DKBLOCK: blklen = mlen; mlen = 0;
 */
	mov	DKBLOCK+1,brg
	add	brg,r6,brg
	mov	brg,r2
	mov	brg,r7
	mov	0,brg
	mov	brg,r6
	mov	brg,r5
	mov	(1<<1),brg
	or	brg,r15
	br	o_blk
o_chunk:
/*
 * mlen > DKBLOCK: blklen = DKBLOCK; mlen -= DKBLOCK;
 */
	inc	r6
	adc	r5
	mov	DKBLOCK,brg
	mov	brg,r2
	mov	brg,r7
o_blk:
/*
 * now wants to send a block with len in r2
 * pklen (r1) = min{r2, DKCHUNK}
 * blklen -= pklen
 */
	mov	DKCHUNK,brg
	sub	brg,r2
	brc	1f
/*
 * r2 < DKCHUNK: r1 = r2; r2 = 0;
 */
	add	brg,r2,brg
	mov	brg,r1
	dec	r1,-
	brz	o_tail		/* go send trailer */
	mov	0,brg
	mov	brg,r2
	br	2f
1:
/*
 * r2 >= DKCHUNK: r1 = DKCHUNK; r2 -= DKCHUNK;
 */
	mov	brg,r1
2:
o_mark:
/*
 * Now send the DKMARK with chan#
 */
	SENDHEAD(r9)
/*
 * output the rest of the data
 * if r13 is odd, get one byte first
 */
	mov	r13,brg
	br0	o_getone
o_gettwo:
/*
 * Get another two bytes of data for this channel
 */
	SGETTWO(r13,r12,r11,o_err_bus)
/*
 * Send two bytes out to CIM
 * if pklen is zero, then issue send-packet command
 * otherwise, go back to get another two bytes
 * Now odh was set to DKDATA
 */
	dec	r1
	BUSWAIT
	SENDDATA(D_WDATA,idl)
	dec	r1		/* pklen-- */
	brz	o_sodd
o_sendhi:
	D422(3)
	SENDDATA(D_WDATA,idh)	/* send the hi byte */
	dec	r1,-		/* pklen-- */
	brz	o_sendpack
	br	o_gettwo
o_getone:
/*
 * get 2 bytes, throw away the low byte
 * send the hi byte
 */
	dec	r13
	mov	0,brg
	subc	brg,r12
	subc	brg,r11		/* back up to even address */
	dec	r1
	GETTWO(r13,r12,r11,o_err_bus)
	br	o_sendhi
o_sodd:
/*
 * hi byte has not been sent yet: dec addr by 1
 */
	mov	0,brg
	dec	r13
	subc	brg,r12
	subc	brg,r11
o_sendpack:
/*
 * if r2 (running blklen) > 0, issue XPACK and goto o_blk
 */
	dec	r2,-
	brz	o_pack2
/*
 * Having loaded a whole packet, now issue the
 * transmit-packet command, i.e. dkcsr=D_XPACK
 */
	CHK(B1_SPK,1)		/* check point */
	D422(2)
	SENDPACK(r1)
	br	o_blk		/* go back to send another packet */
o_pack2:
/*
 * if r7-1 (fixed blklen) & 014 == 014, issue XPACK and send trailer
 *	in the next packet
 * else don't issue XPACK and send trailer in this packet
 */
	dec	r7,brg
	mov	brg,r0
	mov	014,brg
	orn	brg,r0
	brz	1f
	br	o_ta1
1:
	SENDPACK(r1)
	D422(4)
o_tail:
/*
 * just sent a block, now send the trailer
 * MARK+chan# BOT blklen 0 SEQ+C_S
 */
	SENDHEAD(r9)
o_ta1:
	D422(2)
	mov	r15,brg
	br1	o_ta3
o_ta1.5:
	mov	I_BOTM,brg
o_ta2:
	mov	brg,r0
	SENDDATA(D_WCNTL,r0)
	D422(4)
	SENDDATA(D_WDATA,r7)
o_ta2.5:
	D422(4)
	SENDDATA(D_WDATA,ZERO)
	D422(3)
	mov	I_SEQ,brg
	or	brg,r4,brg
	mov	brg,r0
	SENDDATA(D_WCNTL,r0)
	D422(4)
	SENDPACK(r1)
/*
 * C_S++ and set XACK
 */
	inc	r4		/* C_S + 1 */
	mov	WINDOW,brg
	and	brg,r4
	mov	r8,%mar
	mov	C_X1,brg
	add	brg,r10,mar
	mov	mem,r0
	mov	XACK,brg
	or	brg,r0,mem
/*
 * r2 - pklen
 * Now r6/r5 is the real mlen
 * while (mlen && C_S != C_R) {
 */
	mov	r3,brg
	xor	brg,r4,brg
	mov	brg,r0
	mov	DKBMASK,brg
	and	brg,r0
	dec	r0,-
	brz	o_end1
	mov	r15,brg
	br1	o_ta5
	br	o_while
o_ta3:
/*
 * reach end of this xmit buffer
 */
	mov	r15,brg
	br4	o_ta5
o_ta4:
	mov	r8,%mar
	mov	C_X1,brg
	add	brg,r10,mar
	mov	mem,r0
	mov	~XBOTM,brg
	or	brg,r0,-
	brz	1f
	mov	I_BOT,brg
	br	o_ta2
1:
	mov	I_BOTM,brg
	br	o_ta2
o_ta5:
/*
 * check if XCNTL to be sent
 */
	mov	r15,brg
	br4	1f
	br	o_end1		/* no XCNTL */
1:
/*
 * reset bit 4 so that next time around we will not duplicate
 */
	mov	~(1<<4),brg
	and	brg,r15
/*
 * check if blklen<DKBLOCK: send XCNTL in this block
 */
	mov	DKBLOCK,brg
	addn	brg,r7,-
	brz	o_ta1.5		/* send XCNTL in next block */
/*
 * send XCNT in this block: see if in the same chunk
 * if the last chunk size was 12-16, then start a new chunk
 */
	dec	r7,brg
	mov	brg,r0
	mov	~014,brg
	or	brg,r0,-
	brz	o_ta6		/* r7 was 16, 15, 14, or 13 */
	or	brg,r7,-
	brz	o_ta6		/* r7 was 12 */
	br	o_ta8
o_ta6:
/*
 * finish the old chunk, restart with a new chunk
 */
	SENDPACK(r1)
	D422(4)
o_ta7:
	SENDHEAD(r9)
	D422(2)
o_ta8:
	CHK(B1_CNTL,1)
	mov	r8,%mar
	mov	C_XCNTL,brg
	add	brg,r10,mar
	SENDDATA(D_WCNTL,mem)		/* send cntl */
	inc	r7
	br	o_ta4
o_cntl:
/*
 * send XCNTL, if any
 */
	mov	r15,brg
	br4	1f
	br	o_endrobin
1:
/*
 * now send the single XCNTL in a block by itself
 * code should look like:
 *	SENDHEAD(r9)
 *	SENDDATA(D_WCNTL,r1)
 *	mov	I_BOT,brg
 *	mov	brg,r1
 *	SENDDATA(D_WCNTL,r1)
 *	mov	1,r1
 *	SENDDATA(D_WDATA,r1)
 *	br	o_ta2.5
 *
 * the reason we goto o_tail is to save text space and slightly slower
 */
	mov	(1<<1),brg		/* indicate mlen == 0 */
	or	brg,r15
	mov	0,brg			/* is 0, will be 1 later */
	mov	brg,r7
	br	o_ta7
o_done:
/*
 * mlen is 0: we can send CHECK here or do nothing
	mov	I_CHECK,brg
	mov	brg,r1
	CALL(send,s.send)
 */

o_end1:
/*
 * save r4 in C_S
 */
	mov	r8,%mar
	mov	C_S,brg
	add	brg,r10,mar
	mov	r4,mem		/* restore C_S */
o_endrobin:
/*
 * BEWARE issue D_WRITE in the while loop, instead of robin loop.
 * inc r9 and go to robin loop.
 */
	CHK(B1_ENRO,1)		/* check point */
	mov	outq1,mar
	mov	%outq1,%mar
	mov	mem,r2
	br	o_robin
o_bye:
o_disp:
/*
 * return to main dispatch loop
 */
	CHK(B1_EXIT,1)		/* check point */
	mov	%disp2,brg
	mov	brg,pcr
	jmp	disp2
o_err_bus:
/*
 * Unibus request fails to complete within 20 usec
 */
	mov	%err_bus,brg
	mov	brg,pcr
	jmp	err_bus

ii_init:
/*
 * send(r9, I_AINIT);
 */
	mov	I_AINIT,brg
	mov	brg,r1
	CALL(send,s.send)		/* argument in r9, r1 */
	mov	r5,brg		/* r5=0 for init0, r5=1 for init1 */
	br0	i_init1
	br	i_init0
i_init1:
/*
 * set block mode
 * reset TA0-TA3, RSEQ, RBLEN, RULEN
 * release all queues and buffers from C_RB, C_RQ
 */
	CHK(B4_IN1,4)
	mov	r8,%mar
	mov	C_X1,brg
	add	brg,r10,mar
	mov	XBLK,brg
	mov	brg,r0
	or	mem,r0,mem		/* set block mode */
	mov	C_TA0,brg
	add	brg,r10,mar
	mov	0,mem|mar++
	mov	0,mem|mar++
	mov	0,mem|mar++
	mov	0,mem|mar++
	mov	C_RSEQ,brg
	add	brg,r10,mar
	mov	0,mem
	mov	C_RULEN,brg
	add	brg,r10,mar
	mov	0,mem|mar++
	mov	0,mem|mar++		/* RULEN = 0 */
	mov	C_RBLEN,brg
	add	brg,r10,mar
	mov	0,mem|mar++
	mov	0,mem|mar++		/* RBLEN = 0 */
	mov	mem,r2			/* r2 = C_RB */
	brz	i_11
	mov	NIL,mem
	CALL(clean,s.clean)
i_11:
	mov	r8,%mar
	mov	C_RQ,brg
	add	brg,r10,mar
	mov	mem,r2			/* r2 = C_RQ */
	brz	ii_loop
	mov	NIL,mem
	CALL(clean,s.clean)
	br	ii_loop
 
i_init0:
/*
 * set char mode
 */
	CHK(B4_IN0,4)
	mov	r8,%mar
	mov	C_X1,brg
	add	brg,r10,mar
	mov	~XBLK,brg
	mov	brg,r0
	and	mem,r0,mem		/* set char mode */
	br	ii_loop

ii_ainit:
/*
 * S = 1, R = 0, A = 0;
 * X = XACT;
 */
	CHK(B4_AIN,4)
	mov	r8,%mar
	mov	C_S,brg
	add	brg,r10,mar
	mov	1,mem|mar++		/* S = 1 */
	mov	0,mem|mar++		/* R = 0 */
	mov	0,mem			/* A = 0 */
	mov	C_X,brg
	add	brg,r10,mar
	mov	XACT,mem|mar++
	mov	mem,r0			/* C_X1 */
	mov	XNIL,brg
	orn	brg,r0,-
	brz	i_ai5			/* send trailer only */
	mov	C_XLEN,brg
	add	brg,r10,mar
	mov	mem,r0|mar++
	or	mem,r0
	mov	C_XCNTL,brg
	add	brg,r10,mar
	or	mem,r0
	dec	r0,-
	brz	ii_loop
/*
 * this channel is output active: put it in 'outq'
 */
	GETQ(r1,o_noqb)
	mov	NIL,mem|mar++
	mov	r9,mem
	mov	%outq,%mar
	mov	outq,mar
i_ai2:
	mov	mem,r2
	brz	i_ai3
	QA(r2)
	br	i_ai2
i_ai3:
	mov	r1,mem
	br	ii_loop
i_ai5:
/*
 * send trailer-only mode
 */
	CALL(strailer,s.strailer)
	br	ii_loop

ii_req:
/*
 * send I_INIT1
 * X = XINIT;
 */
	CHK(B4_IREQ,4)
	mov	I_INIT1,brg
	mov	brg,r1
	CALL(send,s.send)
	mov	r8,%mar
	mov	C_X,brg
	add	brg,r10,mar
	mov	XINIT,mem
	br	ii_loop

ii_enq:
/*
 * send C_C
 */
	CHK(B3_ENQ,3)
	mov	r8,%mar
	mov	C_C,brg
	add	brg,r10,mar
	mov	mem,r1
	CALL(send,s.send)
ii_check:
/*
 * send ACK+C_RSEQ
 * release C_RB
 */
	CHK(B3_CHK,3)
	mov	r8,%mar
	mov	C_RSEQ,brg
	add	brg,r10,mar
	mov	mem,r1
	mov	I_ACK,brg
	or	brg,r1
	CALL(send,s.send)
	mov	r8,%mar
	mov	C_RB,brg
	add	brg,r10,mar
	mov	mem,r2
	brz	ii_loop
	mov	NIL,mem
	CALL(clean,s.clean)
	mov	%i_ebmode,brg
	mov	brg,pcr
	jmp	i_ebmode

ii_eoi:
/*
 * if TA0==SOI and TA1==2, then report KS_EOI
 * TA0,TA1 = 0;
 */
	CHK(B4_EOI,4)
	mov	r8,%mar
	mov	C_TA0,brg
	add	brg,r10,mar
	mov	mem,r7
	mov	0,mem|mar++
	mov	mem,r6
	mov	0,mem|mar++
	mov	I_SOI,brg
	addn	brg,r7,-
	brz	1f
	br	ii_loop
1:
	mov	2,brg
	addn	brg,r6,-
	brz	1f
	br	ii_loop
1:
/*
 * report 2 bytes in TA2, TA3
 */
	mov	mem,r7|mar++	/* TA2 */
	mov	mem,r6		/* TA3 */
	mov	%repinfo,%mar
	mov	repinfo,mar
	mov	KS_EOI,mem|mar++
	mov	r7,mem|mar++	/* lo byte */
	mov	r6,mem|mar++	/* hi byte */
	br	ii_rpt		/* goto CALL(report,s.report) */

ii_tdkcl:
/*
 * rcv a tdk control char, report tdk cntl
 */
	mov	repinfo,mar
	mov	%repinfo,%mar
	mov	KS_CNTL,mem|mar++
	mov	0,mem|mar++
	mov	0,mem|mar++
	mov	r1,mem|mar++
ii_rpt:
	CALL(report,s.report)
ii_loop:
/*
 * return to i_loop
 */
	mov	%i_loop,brg
	mov	brg,pcr
	jmp	i_loop
o_noqb:
/*
 * run out of queues and buffers
 */
	mov	%noqb,brg
	mov	brg,pcr
	jmp	noqb

endseg1: