xref: /original-bsd/sys/vax/mdec/tmscpboot.c (revision f30d0e19)
1*f30d0e19Sbostic /*
2*f30d0e19Sbostic  *	@(#)tmscpboot.c	7.2 (Berkeley) 01/22/88
3*f30d0e19Sbostic  *
4*f30d0e19Sbostic  * TK50 tape boot block for distribution tapes
5*f30d0e19Sbostic  * works on Q-bus tk50 drive on uVaxen
6*f30d0e19Sbostic  *
7*f30d0e19Sbostic  * Rick Lindsley
8*f30d0e19Sbostic  * richl@tektronix.tek.com
9*f30d0e19Sbostic  *
10*f30d0e19Sbostic  * reads a program from a tp directory on a tape and executes it
11*f30d0e19Sbostic  * program must be stripped of the header and is loaded ``bits as is''
12*f30d0e19Sbostic  * you can return to this loader via ``ret'' as you are called ``calls $0,ent''
13*f30d0e19Sbostic  */
141bd76246Sbostic 	.set	RELOC,0x70000
151bd76246Sbostic /* tp directory definitions */
161bd76246Sbostic 	.set	FILSIZ,38	# tp direc offset for file size
171bd76246Sbostic 	.set	BNUM,44		# tp dir offset for start block no.
181bd76246Sbostic 	.set	ENTSIZ,64	# size of 1 TP dir entry, bytes
191bd76246Sbostic 	.set	PTHSIZ,32	# size of TP path name, bytes
201bd76246Sbostic 	.set	BLKSIZ,512	# tape block size, bytes
211bd76246Sbostic 	.set	NUMDIR,24	# no. of dir blocks on tape
221bd76246Sbostic 	.set	ENTBLK,8	# no. of dir entries per tape block
231bd76246Sbostic /* processor registers and bits */
241bd76246Sbostic 	.set	RXCS,32
251bd76246Sbostic 	.set	RXDB,33
261bd76246Sbostic 	.set	TXCS,34
271bd76246Sbostic 	.set	TXDB,35
281bd76246Sbostic 	.set	RXCS_DONE,0x80
291bd76246Sbostic 	.set	TXCS_RDY,0x80
301bd76246Sbostic 	.set	TXCS_pr,7	/* bit position of TXCS ready bit */
311bd76246Sbostic 	.set	RXCS_pd,7	/* bit position of RXCS done bit */
321bd76246Sbostic /* UBA registers */
331bd76246Sbostic 	.set	MAPSTART,0x20088000	# for a uVax, anyway
341bd76246Sbostic 	.set	UBAMEM,0x1ffc2000	# again, for a uVax
351bd76246Sbostic 	.set	MRV,0x80000000		# map register valid bit
361bd76246Sbostic /* TMSCP UBA registers */
371bd76246Sbostic 	.set	TMSCP_CSR, 0774500	# CSR of tk50
381bd76246Sbostic 	.set	TMSCPip,0		# initialization and polling
391bd76246Sbostic 	.set	TMSCPsa,2		# status and address
401bd76246Sbostic /* handy values for tmscp communication area */
411bd76246Sbostic 	.set	TMSCP_OWN,0x80000000
421bd76246Sbostic 	.set	TMSCP_ERR,0x8000
431bd76246Sbostic 	.set	TMSCP_STEP4,0x4000
441bd76246Sbostic 	.set	TMSCP_STEP3,0x2000
451bd76246Sbostic 	.set	TMSCP_STEP2,0x1000
461bd76246Sbostic 	.set	TMSCP_STEP1,0x800
471bd76246Sbostic 	.set	TMSCP_IE,0x80
481bd76246Sbostic 	.set	TMSCP_GO,1
491bd76246Sbostic /* handy offsets into tmscp communication area (from tmscpca) */
501bd76246Sbostic 	.set	cmdint,4
511bd76246Sbostic 	.set	rspint,6
521bd76246Sbostic 	.set	rspdsc,8
531bd76246Sbostic 	.set	cmddsc,12
541bd76246Sbostic /* handy offsets into mscp packets (from %rCMD or %rRSP) */
551bd76246Sbostic 	.set	msglen,0
561bd76246Sbostic 	.set	vcid,3
571bd76246Sbostic 	.set	unit,8
581bd76246Sbostic 	.set	op,12
591bd76246Sbostic 	.set	status,14
601bd76246Sbostic 	.set	modifier,14
611bd76246Sbostic 	.set	bytecnt,16
621bd76246Sbostic 	.set	cntflgs,18
631bd76246Sbostic 	.set	buffer,20
641bd76246Sbostic 	.set	tmkcnt,20
651bd76246Sbostic 	.set	lbn,32
661bd76246Sbostic 	.set	dscptr,40
671bd76246Sbostic /* TMSCP commands and modifiers */
681bd76246Sbostic 	.set	M_OP_STCON,4
691bd76246Sbostic 	.set	M_OP_ONLIN,9
701bd76246Sbostic 	.set	M_OP_READ,33
711bd76246Sbostic 	.set	M_OP_REPOS,37
721bd76246Sbostic 	.set	M_MD_REWND,2
731bd76246Sbostic 	.set	M_MD_IMMED,0x80
741bd76246Sbostic 	.set	M_MD_CLSEX,0x200
751bd76246Sbostic 	.set	M_ST_MASK,0x1f
761bd76246Sbostic 	.set	M_ST_TAPEM,14
771bd76246Sbostic /* miscellaneous */
781bd76246Sbostic 	.set	IUR, 0x37
791bd76246Sbostic 	.set	SID, 0x3e
801bd76246Sbostic 	.set	VAX_630,8
811bd76246Sbostic /* local stack variables */
821bd76246Sbostic 	.set	tmscpca,-240-PTHSIZ-26	# struct tmscpca (see tmscpreg.h)
831bd76246Sbostic 	.set	rsp,-240-PTHSIZ-10	# tmscp response area
841bd76246Sbostic 	.set	cmd,-120-PTHSIZ-10	# tmscp command area
851bd76246Sbostic 	.set	name,-PTHSIZ-10		# operator-typed file name
861bd76246Sbostic 	.set	dirread,-10		# is the tape directory incore already?
871bd76246Sbostic 	.set	mtapa,-8		# cur tape addr (last blk we read)
881bd76246Sbostic 	.set	tapa,-4			# desired tape addr (inclusive)
891bd76246Sbostic /* register usage */
901bd76246Sbostic 	.set	rCMD,r7
911bd76246Sbostic 	.set	rRSP,r8
921bd76246Sbostic 	.set	rUBADDR,r9
931bd76246Sbostic 	.set	rMAPREGS,r10
941bd76246Sbostic 	.set	rCSR,r11
951bd76246Sbostic /* ===== */
961bd76246Sbostic 
971bd76246Sbostic /* initialization */
981bd76246Sbostic init:
991bd76246Sbostic 	#
1001bd76246Sbostic 	# if on a uVax, we were loaded by VMB from tape. We also have
1011bd76246Sbostic 	# only one unibus, at 0x1fffc2000 (see above). Elstwise, this
1021bd76246Sbostic 	# boot program will almost certainly need help.
1031bd76246Sbostic 	#
1041bd76246Sbostic 	mfpr	$SID,r0
1051bd76246Sbostic 	cmpzv	$24,$8,r0,$VAX_630
1061bd76246Sbostic 	beql	1f
1071bd76246Sbostic 	halt
1081bd76246Sbostic 	#
1091bd76246Sbostic 	# We must have been loaded by VMB, and thus we are at a non-zero
1101bd76246Sbostic 	# location.  sp will contain the base address of the area at which
1111bd76246Sbostic 	# we were loaded. So we add sp to $end to get the true end-of-program
1121bd76246Sbostic 	# address.
1131bd76246Sbostic 	#
1141bd76246Sbostic 1:	movl	sp,r6		# r6 - beginning of program
1151bd76246Sbostic 	movl	$RELOC,fp	# core loc to which to move this program
1161bd76246Sbostic 	addl3	$-512,fp,sp	# set stack pointer; leave room for locals
1171bd76246Sbostic 	addl3	$-512,fp,r0	# zero our destination mem .. we start here
1181bd76246Sbostic 	addl3	$end,fp,r1	# and end here
1191bd76246Sbostic clr:	clrl	(r0)+
1201bd76246Sbostic 	cmpl	r0,r1
1211bd76246Sbostic 	jlss	clr
1221bd76246Sbostic 
1231bd76246Sbostic 	movc3	$end,(r6),(fp)	# copy to relocated position
1241bd76246Sbostic 	addl3	$reginit,$RELOC,r0
1251bd76246Sbostic 	jmp	(r0)		# and go there
1261bd76246Sbostic reginit:
1271bd76246Sbostic 	/* initialize our registers. Should need to do this only once */
1281bd76246Sbostic 	addl3	$UBAMEM, $TMSCP_CSR, %rCSR	# set up CSR register
1291bd76246Sbostic 	movl	$MAPSTART, %rMAPREGS	# locate map registers
1301bd76246Sbostic 
1311bd76246Sbostic 	moval	tmscpca(fp), %rUBADDR	# set unibus address for comm area
1321bd76246Sbostic 	extzv	$0,$9,%rUBADDR,%rUBADDR	# format: (MR# << 9) | (&comm & 0x1ff)
1331bd76246Sbostic 	ashl	$-9,$RELOC-512,r0	# setting up map register for our stack
1341bd76246Sbostic 	bisl3	$MRV,r0,(%rMAPREGS)	# mark our stack valid (MR #0)
1351bd76246Sbostic 
1361bd76246Sbostic 	moval	cmd(fp),%rCMD		# location of cmd mscp packet
1371bd76246Sbostic 	moval	rsp(fp),%rRSP		# location of rsp mscp packet
1381bd76246Sbostic 	bsbw	inittmscp		# init the unit
1391bd76246Sbostic 	bsbw	onlin			# set tape online
1401bd76246Sbostic 	bsbw	rew			# rewind tape
1411bd76246Sbostic 
1421bd76246Sbostic start:
143*f30d0e19Sbostic #ifdef DEBUG
144*f30d0e19Sbostic 	movzbl	$11,r0			# newline
145*f30d0e19Sbostic 	bsbw	putc
146*f30d0e19Sbostic 	movzbl	$13,r0			# return
147*f30d0e19Sbostic 	bsbw	putc
148*f30d0e19Sbostic #endif
1491bd76246Sbostic 	movzbl	$'=,r0			# prompt
1501bd76246Sbostic 	bsbw	putc
1511bd76246Sbostic 	bsbw	getname
1521bd76246Sbostic 
1531bd76246Sbostic 	# desired TP filename is in name(fp).  Now read in entire tp directory
1541bd76246Sbostic 	# contents into low core, starting at loc 0. Because tk50's are slow,
1551bd76246Sbostic 	# and because we are going to go over 512 bytes anyway, and because
1561bd76246Sbostic 	# it requires so little effort, we'll keep track of whether the data
1571bd76246Sbostic 	# at location 0 is the tape directory.
1581bd76246Sbostic 
1591bd76246Sbostic 	tstw	dirread(fp)	# if directory needs to be read in, do so
1601bd76246Sbostic 	bneq	1f
1611bd76246Sbostic 	bsbw	readdir
1621bd76246Sbostic 1:
1631bd76246Sbostic 	#
1641bd76246Sbostic 	# all of directory is now in locore, @ 0.
1651bd76246Sbostic 	# search for filename; return to start if it isn't there.
1661bd76246Sbostic 	#
1671bd76246Sbostic 	clrl	r0			# start at location 0
1681bd76246Sbostic nxtdir:	moval	name(fp),r2
1691bd76246Sbostic 	movl	r0,r1
1701bd76246Sbostic 1:	cmpb	(r1),(r2)
1711bd76246Sbostic 	bneq	2f
1721bd76246Sbostic 	tstb	(r1)
1731bd76246Sbostic 	beql	found
1741bd76246Sbostic 	incl	r1
1751bd76246Sbostic 	incl	r2
1761bd76246Sbostic 	brb	1b
1771bd76246Sbostic 2:	acbl	$NUMDIR*BLKSIZ-1,$ENTSIZ,r0,nxtdir
1781bd76246Sbostic 	brw	start			# entry not in directory; start over
1791bd76246Sbostic 
1801bd76246Sbostic 	# entry IS here; read it in from tape
1811bd76246Sbostic 
1821bd76246Sbostic found:	movzwl	BNUM(r0),tapa(fp)	# start block no., 2 bytes
1831bd76246Sbostic 	addl2	$2-1,tapa(fp)		# skip over this program (2 blocks)
1841bd76246Sbostic 					# minus 1 because we will read THROUGH
1851bd76246Sbostic 					# this block; so we want to stop just
1861bd76246Sbostic 					# before it
1871bd76246Sbostic 	movzwl	FILSIZ(r0),r4		# low 2 bytes file size
1881bd76246Sbostic 	insv	FILSIZ-1(r0),$16,$8,r4  # file size, high byte
1891bd76246Sbostic 	cmpl	r4,$RELOC-512		# check if file fits below stack
1901bd76246Sbostic 	bgeq	start 			# file too large
1911bd76246Sbostic 
1921bd76246Sbostic 	# Now advance to proper place on tape. tapa has our
1931bd76246Sbostic 	# desired address
1941bd76246Sbostic 
1951bd76246Sbostic 	clrw	dirread(fp)	# we are about to obliterate our incore copy
1961bd76246Sbostic 				# of the directory
1971bd76246Sbostic 2:	clrl	r3	# rrec expects r3 to point to a buffer. 0 will do ...
1981bd76246Sbostic 	bsbw	rrec
1991bd76246Sbostic 	cmpl	mtapa(fp),tapa(fp)
2001bd76246Sbostic 	blss	2b
2011bd76246Sbostic 
2021bd76246Sbostic 	# tape now positioned correctly. Read in program. Number of bytes
2031bd76246Sbostic 	# to read is in r4. We must round up to an even BLKSIZ boundary.
2041bd76246Sbostic 	# Clear the area we are putting it at; unix expects zeroes in its
2051bd76246Sbostic 	# data and bss section.
2061bd76246Sbostic 
2071bd76246Sbostic 	addl2	$BLKSIZ-1,r4		# round up
2081bd76246Sbostic 	bicl2	$BLKSIZ-1,r4		# mask out
2091bd76246Sbostic 	movl	r4,r5			# use r5; need to save r4 for later
2101bd76246Sbostic 1:	clrl	(r5)
2111bd76246Sbostic 	sobgtr	r5,1b
2121bd76246Sbostic 
2131bd76246Sbostic 	# now read in file.
2141bd76246Sbostic 
2151bd76246Sbostic 	clrl	r3			# read into page 0 (incremented by rrec)
2161bd76246Sbostic 	ashl	$-9,r4,r5		# r5 now holds # blks to read
2171bd76246Sbostic 	addl2	r5,tapa(fp)		# compute desired tape blk #
2181bd76246Sbostic 1:	bsbw	rrec
2191bd76246Sbostic 	cmpl	mtapa(fp),tapa(fp)	# got it yet?
2201bd76246Sbostic 	blss	1b
2211bd76246Sbostic 
2221bd76246Sbostic 	# begin execution. Call as a function.
2231bd76246Sbostic 	clrl	r5
2241bd76246Sbostic 	calls	$0,(r5)
2251bd76246Sbostic 
2261bd76246Sbostic 	# now, since the called function has reset the tape drive for
2271bd76246Sbostic 	# us (!) we must reinit it again ourselves.
2281bd76246Sbostic 
2291bd76246Sbostic 	ashl	$-9,$RELOC-512,r0	# set up map register for our stack
2301bd76246Sbostic 	bisl3	$MRV,r0,(%rMAPREGS)	# mark our stack valid (MR #0)
2311bd76246Sbostic 	bsbw	inittmscp		# re-init drive
2321bd76246Sbostic 	bsbw	onlin			# re-online it
2331bd76246Sbostic 	brw	start
2341bd76246Sbostic 
2351bd76246Sbostic 	# getname will set name(fp) and leave len(name(fp)) in r6
2361bd76246Sbostic getname:moval	name(fp),r1		# mov to register for ease of access
2371bd76246Sbostic nxtc:	bsbw	getc
2381bd76246Sbostic 	cmpb	r0,$012			# end of line?
2391bd76246Sbostic 	beql	nullc
2401bd76246Sbostic 	movb	r0,(r1)+
2411bd76246Sbostic 	brb	nxtc
2421bd76246Sbostic nullc:	moval	name(fp),r0
2431bd76246Sbostic 	subl3	r0,r1,r6		# length of path name
2441bd76246Sbostic 	jeql	start			# just hit return; nothing useful here
2451bd76246Sbostic 	clrb	(r1)+			# add null at end
2461bd76246Sbostic 	incl	r6			# add null to length
2471bd76246Sbostic 	rsb
2481bd76246Sbostic 
2491bd76246Sbostic getc:	mfpr	$RXCS,r0
2501bd76246Sbostic 	bbc	$RXCS_pd,r0,getc	/* receiver ready ? */
2511bd76246Sbostic 	mfpr	$RXDB,r0
2521bd76246Sbostic 	extzv	$0,$7,r0,r0
2531bd76246Sbostic 	cmpb	r0,$015
2541bd76246Sbostic 	bneq	putc
2551bd76246Sbostic 	bsbw	putc
2561bd76246Sbostic 	movb	$0,r0
2571bd76246Sbostic 	bsbw	putc
2581bd76246Sbostic 	movb	$012,r0
2591bd76246Sbostic 
2601bd76246Sbostic putc:	mfpr	$TXCS,r2
2611bd76246Sbostic 	bbc	$TXCS_pr,r2,putc	/* transmitter ready ? */
2621bd76246Sbostic 	extzv	$0,$7,r0,r0
2631bd76246Sbostic 	mtpr	r0,$TXDB
2641bd76246Sbostic 	rsb
2651bd76246Sbostic 
2661bd76246Sbostic inittmscp:
2671bd76246Sbostic 	movw	$0,TMSCPip(%rCSR)		# start step 1
2681bd76246Sbostic 1:	bitw	$TMSCP_STEP1,TMSCPsa(%rCSR)
2691bd76246Sbostic 	beql	1b
270*f30d0e19Sbostic #ifdef DEBUG
271*f30d0e19Sbostic 	movzbl	$'1,r0
272*f30d0e19Sbostic 	bsbw	putc
273*f30d0e19Sbostic #endif
2741bd76246Sbostic init2:	movw	$TMSCP_ERR,TMSCPsa(%rCSR)	# start step 2
2751bd76246Sbostic 2:	bitw	$TMSCP_STEP2,TMSCPsa(%rCSR)
2761bd76246Sbostic 	beql	2b
277*f30d0e19Sbostic #ifdef DEBUG
278*f30d0e19Sbostic 	movzbl	$'2,r0
279*f30d0e19Sbostic 	bsbw	putc
280*f30d0e19Sbostic #endif
2811bd76246Sbostic init3:	addl3	$8,%rUBADDR,r0			# start step 3
2821bd76246Sbostic 	cvtlw	r0,TMSCPsa(%rCSR)
2831bd76246Sbostic 3:	bitw	$TMSCP_STEP3,TMSCPsa(%rCSR)
2841bd76246Sbostic 	beql	3b
285*f30d0e19Sbostic #ifdef DEBUG
286*f30d0e19Sbostic 	movzbl	$'3,r0
287*f30d0e19Sbostic 	bsbw	putc
288*f30d0e19Sbostic #endif
2891bd76246Sbostic init4:	addl3	$8,%rUBADDR,r0			# start step 4
2901bd76246Sbostic 	ashl	$-16,r0,r0
2911bd76246Sbostic 	cvtlw	r0,TMSCPsa(%rCSR)
2921bd76246Sbostic 4:	bitw	$TMSCP_STEP4,TMSCPsa(%rCSR)
2931bd76246Sbostic 	beql	4b
294*f30d0e19Sbostic #ifdef DEBUG
295*f30d0e19Sbostic 	movzbl	$'4,r0
296*f30d0e19Sbostic 	bsbw	putc
297*f30d0e19Sbostic #endif
2981bd76246Sbostic setchar:
2991bd76246Sbostic 	movw	$TMSCP_GO,TMSCPsa(%rCSR)
3001bd76246Sbostic 	moval	140(%rUBADDR),tmscpca+cmddsc(fp)
3011bd76246Sbostic 	moval	tmscpca+cmddsc(fp),dscptr(%rCMD)
3021bd76246Sbostic 	movb	$1,vcid(%rCMD)
3031bd76246Sbostic 	moval	20(%rUBADDR),tmscpca+rspdsc(fp)
3041bd76246Sbostic 	moval	tmscpca+rspdsc(fp),dscptr(%rRSP)
3051bd76246Sbostic 	clrw	cntflgs(%rCMD)
3061bd76246Sbostic 
3071bd76246Sbostic 	movb	$M_OP_STCON,op(%rCMD)
3081bd76246Sbostic 	clrw	modifier(%rCMD)
3091bd76246Sbostic 	clrl	buffer(%rCMD)
3101bd76246Sbostic 	clrl	bytecnt(%rCMD)
3111bd76246Sbostic 	bsbw	tmscpcmd
312*f30d0e19Sbostic #ifdef DEBUG
313*f30d0e19Sbostic 	movzbl	$'S,r0
314*f30d0e19Sbostic 	bsbw	putc
315*f30d0e19Sbostic #endif
3161bd76246Sbostic 	rsb
3171bd76246Sbostic 
3181bd76246Sbostic tmscpcmd:
3191bd76246Sbostic 	movw	$116,msglen(%rCMD)		# 116 -- size of an mscp packet
3201bd76246Sbostic 	bisl2	$TMSCP_OWN,tmscpca+cmddsc(fp)
3211bd76246Sbostic 	movw	$116,msglen(%rRSP)
3221bd76246Sbostic 	bisl2	$TMSCP_OWN,tmscpca+rspdsc(fp)
3231bd76246Sbostic 	movw	TMSCPip(%rCSR),r0		# start polling
3241bd76246Sbostic wait:	cvtwl	TMSCPsa(%rCSR),r0
3251bd76246Sbostic 	bitl	$TMSCP_ERR,r0
3261bd76246Sbostic 	beql	1f
3271bd76246Sbostic 	movw	modifier(%rRSP),r1	# so we can read status easily
3281bd76246Sbostic 	halt				# some error or other
3291bd76246Sbostic 1:	tstl	tmscpca+4(fp)
3301bd76246Sbostic 	beql	2f
3311bd76246Sbostic 	clrw	tmscpca+4(fp)
3321bd76246Sbostic 2:	bitl	$TMSCP_OWN,tmscpca+rspdsc(fp)
3331bd76246Sbostic 	bneq	wait
3341bd76246Sbostic 
3351bd76246Sbostic 	# cmd done
3361bd76246Sbostic 
3371bd76246Sbostic 	clrw	tmscpca+rspint(fp)
3381bd76246Sbostic 	extzv	$0,$5,status(%rRSP),r0
3391bd76246Sbostic 	tstl	r0
3401bd76246Sbostic 	beql	ok			# no errors
3411bd76246Sbostic 	cmpl	$M_ST_TAPEM, r0
3421bd76246Sbostic 	beql	ok			# not an error, just a tape mark
3431bd76246Sbostic 	halt				# some unknown error
3441bd76246Sbostic ok:	rsb
3451bd76246Sbostic 
3461bd76246Sbostic rew:	movb	$M_OP_REPOS,op(%rCMD)
3471bd76246Sbostic 	movw	$M_MD_REWND|M_MD_IMMED,modifier(%rCMD)
3481bd76246Sbostic 	clrl	buffer(%rCMD)
3491bd76246Sbostic 	clrl	bytecnt(%rCMD)
3501bd76246Sbostic 	bsbw	tmscpcmd
351*f30d0e19Sbostic #ifdef DEBUG
352*f30d0e19Sbostic 	movzbl	$'r,r0			# to indicate r)ewind
353*f30d0e19Sbostic 	bsbw	putc
354*f30d0e19Sbostic #endif
3551bd76246Sbostic 	movl	$-1,mtapa(fp)		# no blocks read yet
3561bd76246Sbostic 	rsb
3571bd76246Sbostic 
3581bd76246Sbostic onlin:	movb	$M_OP_ONLIN,op(%rCMD)
3591bd76246Sbostic 	clrw	modifier(%rCMD)
3601bd76246Sbostic 	clrl	buffer(%rCMD)
3611bd76246Sbostic 	clrl	bytecnt(%rCMD)
3621bd76246Sbostic 	bsbw	tmscpcmd
363*f30d0e19Sbostic #ifdef DEBUG
364*f30d0e19Sbostic 	movzbl	$'O,r0			# to indicate O)nline
365*f30d0e19Sbostic 	bsbw	putc
366*f30d0e19Sbostic #endif
3671bd76246Sbostic 	rsb
3681bd76246Sbostic 
3691bd76246Sbostic 	# Read the tp directory. Number of blocks to read is in tapa(fp),
3701bd76246Sbostic 	# and will be read into memory starting at location 0.
3711bd76246Sbostic readdir:bsbw	rew			# beginning of tape
3721bd76246Sbostic 	addl3	$2,$NUMDIR,tapa(fp)	# blocks to read (skip this 1k program)
3731bd76246Sbostic 	clrl	r3			# using mem starting at 0 as free space
3741bd76246Sbostic 	bsbw	rrec; bsbw rrec		# read and discard first two blocks --
3751bd76246Sbostic 					# those are this program
3761bd76246Sbostic 	bsbw	rrec			# read and discard first tp block
3771bd76246Sbostic 	clrl	r3			# reset starting place
3781bd76246Sbostic 	incw	dirread(fp)		# show that directory is incore
3791bd76246Sbostic 1:	bsbw	rrec
3801bd76246Sbostic 	cmpl	mtapa(fp),tapa(fp)	# done yet?
3811bd76246Sbostic 	blss	1b
3821bd76246Sbostic 	rsb
3831bd76246Sbostic 
3841bd76246Sbostic 	# read 1 block from mag tape into page indicated by r3, which will
3851bd76246Sbostic 	# automatically be incremented here. mtapa is also advanced.
3861bd76246Sbostic 
3871bd76246Sbostic rrec:	bisl3	$MRV,r3,4(%rMAPREGS)	# using map register #1
3881bd76246Sbostic 	movl	$BLKSIZ,bytecnt(%rCMD)	# how much to read
3891bd76246Sbostic 	ashl	$9,$1,buffer(%rCMD)	# indicating mr #1. We just happen to
3901bd76246Sbostic 					# be on a page boundary, so filling in
3911bd76246Sbostic 					# the low 9 bits is not necessary.
3921bd76246Sbostic 	movb	$M_OP_READ,op(%rCMD)
3931bd76246Sbostic 	clrw	modifier(%rCMD)
3941bd76246Sbostic 	bsbw	tmscpcmd
395*f30d0e19Sbostic #ifdef DEBUG
396*f30d0e19Sbostic 	movzbl	$'R,r0			# to indicate R)ead a record
397*f30d0e19Sbostic 	bsbw	putc
398*f30d0e19Sbostic #endif
3991bd76246Sbostic 	incl	mtapa(fp)
4001bd76246Sbostic 	incl	r3
4011bd76246Sbostic 	rsb
4021bd76246Sbostic end:
403