SysIII/usr/src/uts/pdp11/up/dzb/subs.s

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

/*
 * Subroutines 
 */

	.org	3072

seg3:

/*
 * KMC initialization
 */
init:
	mov	0,brg
	mov	brg,r13
	mov	brg,r14
	mov	brg,csr2
	mov	IEO,brg
	mov	brg,csr0
/*
 * Initialize the free-buffer list
 */
#define	NPQ	3
#define	NQE	(NPQ*256-((inqueue+3)&~3))/4
/*
 * Define the number of 16-byte input buffers
 */
#define	NBUF	16*(16-4-NPQ)
	mov	NPQ,brg
	mov	brg,r0
	mov	NBUF-1,brg
	mov	brg,r1
	mov	NIL,brg
	mov	brg,r11
init2:
	RELEASE(r0);
	mov	16,brg
	add	brg,r0
	adc	r0
	dec	r1
	brc	init2
/*
 * Initialize the list of available queue entries
 */
	mov	NIL,brg
	mov	brg,r12
	mov	(inqueue+3)&~3,brg
	mov	brg,r0
	mov	NQE-1,brg
	mov	brg,r1
init4:
	FREEQ(r0)
	mov	4,brg
	add	brg,r0
	adc	r0
	dec	r1
	brc	init4
/*
 * Initialize LTE queue pointers
 */
	mov	3,brg
	mov	brg,r8
init6:
	mov	%dzst,brg
	add	brg,r8,%mar
	mov	7,r7|mar
init8:
	mov	mem,r10
	mov	OUTBUF,brg
	add	brg,r10,mar
	mov	NIL,mem|mar++
	mov	NIL,mem|mar++
	mov	NIL,mem
	dec	r7,r7|mar
	brc	init8
	dec	r8
	brc	init6
/*
 * Return to caller
 */
	RETURN

/*
 * Carrier-on status check--executed once every 12.8 msec for each DZ
 */
mdmcheck:
/*
 * If the 12.8 millisecond timer hasn't expired yet
 * then go to disp
 */
	mov	clock2,mar
	mov	mem,r0
	dec	r0,mem
	brc	dispret3
/*
 * Set up a unibus request for the current value of MSR
 */
	mov	csrget,mar
	mov	mem,r2|mar++
	mov	mem,r1|mar++
	mov	mem,r0
	mov	6,brg
	add	brg,r2,brg
	mov	brg,ial
	adc	r1,brg
	mov	brg,iah
	adc	r0
	mov	3,brg
	and	brg,r0
	asl	r0
	asl	r0
	mov	NRQ,brg
	or	brg,r0,npr
/*
 * Wait for the unibus transfer to complete.
 * If an error occurs then go to buserr3.
 */
	BUSWAIT(buserr3)
/*
 * Get the previous value of the carrier-on status indicators
 * and save the new value.  If the new value is the same as the
 * previous value then go to disp
 */
	mov	costatus,mar
	mov	mem,r2
	mov	idh,mem
	addn	mem,r2,-
	brz	dispret3
/*
 * Initialize regs for loop which follows
 */
	mov	0,brg
	mov	brg,r7
	mov	1,r1
/*
 * Set a bit in r2 for each line with changed status
 */
	xor	mem,r2
	mov	mem,r3
/*
 * Step through all lines for this DZ.
 *
 * For each line with changed status, set the carrier-on
 * flag on or off as appropriate
 */
mdmchk2:
	mov	r1,brg
	orn	brg,r2,-
	brz	1f
	br	2f
1:
	mov	r7,mar
	mov	mem,r10
	mov	FLAGS,brg
	add	brg,r10,mar
	mov	mem,r0
	mov	r1,brg
	orn	brg,r3,-
	brz	1f
	mov	~CARR_ON,brg
	and	brg,r0,mem
	br	2f
1:
	mov	CARR_ON,brg
	or	brg,r0,mem
2:
	asl	r1
	inc	r7
	mov	7,brg
	addn	brg,r7,-
	brc	1f
	br	mdmchk2
1:
/*
 * If a carrier-on change report has already been requested for this DZ
 * then go to disp
 */
	mov	status,mar
	mov	mem,r2
	mov	1<<2,brg
	orn	brg,r2,-
	brz	dispret3
	mov	1<<2,brg
	or	brg,r2,mem
/*
 * Insert the page for the current DZ at the end of the
 * coc-report-needed queue
 */
	mov	coclink,mar
	mov	NIL,mem
	mov	tailcocq,mar
	mov	%tailcocq,%mar
	mov	mem,r0
	brz	1f
	mov	r8,mem
	mov	%dzst,brg
	add	brg,r0,%mar
	mov	coclink,mar
	mov	r8,mem
	br	2f
1:
	mov	headcocq,mar
	mov	r8,mem|mar++
	mov	r8,mem
2:
/*
 * Set the global flag which indicates that a
 * carrier-on change report has been requested
 */
	mov	CHKCOCQ,brg
	or	brg,r14
/*
 * Go to disp
 */
	br	.
	br	dispret3
/*
 * The 50-microsecond hardware timer has expired
 */
tick:
/*
 * Reset the 50-microsecond timer
 */
	mov	nprx,r0
	mov	~(BRQ|ACLO|(3<<2)),brg
	and	brg,r0
	mov	PCLK,brg
	or	brg,r0,nprx
/*
 * The effect of the following code is to schedule a
 * csr check for a different DZ every 50(?) microseconds.
 * Since there are four possible DZ's, each DZ gets scheduled
 * for a csr check every 200 microseconds.  This is approximately
 * a factor of five better than we need for 9600 baud (one character
 * every 1042 microseconds).
 */
/*
 * Increment r15.
 */
	inc	r15
/*
 * Set the DZ number from bits 1-0 of r15.
 */
	mov	3,brg
	and	brg,r15,brg
	mov	brg,r8
/*
 * Set page register to page for this DZ
 */
	mov	%dzst,brg
	add	brg,r8,%mar
/*
 * If a base-in command has not been received yet for this DZ
 * then go to disp
 */
	mov	status,mar
	mov	mem,brg
	br7	1f
	br	dispret3
1:
/*
 * If a csr check has already been requested for this DZ
 * then go to delaycheck
 */
	br0	delaycheck
/*
 * Set the bit which indicates that a csr check has already
 * been scheduled
 */
	mov	1<<0,r1
	or	mem,r1,mem
/*
 * Insert the page for the current DZ at the end of the
 * csr-check-needed queue
 */
	mov	csrlink,mar
	mov	NIL,mem
	mov	tailcsrq,mar
	mov	%tailcsrq,%mar
	mov	mem,r0
	brz	1f
	mov	r8,mem
	mov	%dzst,brg
	add	brg,r0,%mar
	mov	csrlink,mar
	mov	r8,mem
	br	2f
1:
	mov	headcsrq,mar
	mov	r8,mem|mar++
	mov	r8,mem
2:
/*
 * Set global flag to indicate that a csr check has been requested
 */
	mov	CHKCSRQ,brg
	or	brg,r14
delaycheck:
/*
 * Set page register to page for this DZ
 */
	mov	%dzst,brg
	add	brg,r8,%mar
/*
 * Decrement the 16.7 msec timer.  If the result is 
 * non-negative then go to mdmcheck
 */
	mov	clock1,mar
	mov	mem,r0
	dec	r0,mem
	brc	dispret3	/* *** temp for testing *** */
/*	brc	mdmcheck	*/
/*
 * Reset the 16.7 msec timer
 */
	mov	50,mem
/*
 * The 16.7 msec timer has expired.  Therefore we need to decrement
 * the count field for each lte which is currently in the twait
 * state (delaying)
 */
/*
 * Initialize registers for loop which follows
 */
	mov	5,r5
	mov	7,r7|mar
/*
 * The following loop is executed once for each lte
 * in the page for the selected DZ.
 *
 * If we find a line which is in the twait state
 * then we decrement the count field of the lte.
 * If the result is negative then we put the line
 * back into state 1 and enable the line.
 */
delaych1:
/*
 * Get the address of the lte
 *
 * If state == 5 (twait) then go to delaych3
 *
 * Note that the following code assumes that STATE is the
 * first cell in the lte and that the memory-address
 * register (mar) has already been loaded from r7
 */
	mov	mem,r10|mar
	addn	mem,r5,-
	brz	delaych3
/*
 * Test for end of loop
 */
delaych2:
/*
 * Decrement the current entry number.  If the result is
 * non-negative then go to delaych1
 */
	dec	r7,r7|mar
	brc	delaych1
/*
 * Go to delaych4
 */
	br	delaych4
/*
 * We get here when we find a line with STATE == 5 (twait)
 */
delaych3:
/*
 * Decrement the count field of the lte.  If the result is
 * non-negative then go to delaych2
 */
	mov	COUNT,brg
	add	brg,r10,mar
	mov	mem,r0
	dec	r0,mem
	brc	delaych2
/*
 * The time has elapsed, if a break was being transmitted call ubreak
 */
	mov	FLAGS1,brg
	add	brg,r10,mar
	mov	mem,r0
	mov	OUTBRK,brg
	orn	brg,r0,-
	brz	1f
	br	2f
1:
/*
 * Turn off treak bit
 */
	CALL(ubreak)
	mov	%dzst,brg
	add	brg,r8,%mar
	br	delaych2
2:
/*
 * Continue sending data.
 */
/*
 * Set state = 1 (sending normal data)
 */
	mov	STATE,brg
	add	brg,r10,mar
	mov	1,mem
/*
 * Turn on the enable bit for this line
 */
	CALL(enable)
	mov	%dzst,brg
	add	brg,r8,%mar
/*
 * Go to delaych2
 */
	br	delaych2
/*
 * End of above loop
 */
delaych4:
/*
 * Input time-out test
 *
 * Loop through all eight lines for this DZ.  For each line with a non-empty
 * input queue, if the timer has expired then put the line on the 
 * input-ready queue
 */
	mov	7,r7
1:
	mov	r7,mar
	mov	mem,r10
/*
 * See if timer is active
 */
	mov	FLAGS1,brg
	add	brg,r10,mar
	mov	mem,r0
	mov	TIMACT,brg
	orn	brg,r0,-
	brz	2f
	br	3f
2:
/*
 * Timer is active, decrement ITIME
 */
	mov	ITIME,brg
	add	brg,r10,mar
	mov	mem,r0
	dec	r0,mem
	brc	3f
/*
 * Timer has expired, queue input and reset TIMER
 */
	mov	FLAGS1,brg
	add	brg,r10,mar
	mov	mem,r0
	mov	~TIMACT,brg
	and	brg,r0,mem
	CALL(queue)
	mov	%dzst,brg
	add	brg,r8,%mar
3:
	dec	r7
	brc	1b
/*
 * Return to dispatcher
 */
	br	dispret3
/*
 * The following code checks for output character completions
 * and input data ready in the silo
 */
csrcheck:
/*
 * If the check-CSR queue is empty then error
 */
	mov	headcsrq,mar
	mov	%headcsrq,%mar
	mov	mem,r8
	brz	csrcout
	mov	%dzst,brg
	add	brg,r8,%mar
/*
 * Set up a unibus request for the current value of CSR
 */
	mov	csrget,mar
	mov	mem,ial|mar++
	mov	mem,iah|mar++
	mov	mem,r0
	asl	r0
	asl	r0
	mov	NRQ,brg
	or	brg,r0,npr
/*
 * Wait for the unibus transfer to complete.
 * If an error occurs then go to buserr0.
 */
	BUSWAIT(buserr3)
/*
 * If there is an input character available then go to csrchk2
 */
	mov	idl,brg
	br7	csrchk2
/*
 * If there is an output data request then go to csrchk4
 */
	mov	idh,brg
	br7	csrchk4
/*
 * Clear the bit that indicates that a csr check has been scheduled for this page
 */
	mov	status,mar
	mov	 ~(1<<0),brg
	mov	brg,r0
	and 	mem,r0,mem
/*
 * Remove the current DZ from the csr-check-needed queue;
 * if the queue is empty then clear the CHKCSRQ bit in r14
 */
	mov	csrlink,mar
	mov	mem,brg
	mov	%headcsrq,%mar
	mov	headcsrq,mar
	mov	brg,mem|mar++
	brz	1f
	br	2f
1:
	mov	brg,mem
csrcout:
	mov	~CHKCSRQ,brg
	and	brg,r14
2:
/*
 * Go to disp
 */
	br	dispret3
/*
 * Input data available--jump to input segment
 */
csrchk2:
	mov	%inchar,brg
	mov	brg,pcr
	jmp	inchar
/*
 * Output data request--jump to output segment
 */
csrchk4:
	mov	%outreq,brg
	mov	brg,pcr
	jmp	outreq

dispret3:
	mov	%disp,brg
	mov	brg,pcr
	jmp	disp
/*
 * The following code queues and error report
 */
erqueue:
/*
 * If an error has already been queued for this dz just return
 */
	mov	%dzst,brg
	add	brg,r8,%mar
	mov	status,mar
	mov	mem,r0
	mov	1<<5,brg
	orn	brg,r0,-
	brz	2f
	or	brg,r0,mem
/*
 * Increment the error counter
 */
	mov	errcnt,mar
	mov	mem,r0
	inc	r0,mem
/*
 * Get the driver's idea of the DZ number and combine it with the line
 * number to get the minor device number
 */
	mov	dznr,mar
	mov	mem,r0
	asl	r0
	asl	r0
	asl	r0
	mov	07,brg
	and	brg,r7,brg
	or	brg,r0
/*
 * Queue an error for this line
 */
	GETQ(r4,queuerr3)
	mov	NIL,mem|mar++
/*
 * Put dznr<<3|line number in second byte
 */
	mov	r0,mem|mar++
/*
 * Put error number into third byte
 */
	mov	r1,mem|mar++
/*
 * Save r8
 */
	mov	r8,mem
	mov	%tailerrq,%mar
	mov	tailerrq,mar
	mov	mem,r0
	brz	1f
	mov	r4,mem
	mov	03,brg
	and	brg,r0,%mar
	mov	~03,brg
	and	brg,r0,mar
	mov	r4,mem
	br	2f
1:
	mov	headerrq,mar
	mov	r4,mem|mar++
	mov	r4,mem
/*
 * Indicat an error queued
 */
2:
	mov	CHKERRQ,brg
	or	brg,r14
	RETURN

/*
 * Unibus error
 */
buserr3:
/*
 * Clear the non-existent memory bit
 */
	mov	nprx,r0
	mov	~(BRQ|ACLO|NEM),brg
	and	brg,r0,nprx
	ERROR(BUSERR3)
	br	dispret3
queuerr3:
/*
 * No queue entries to queue an error, tough
 */
	br	.

endseg3: