xref: /csrg-svn/sys/vax/mdec/tuboot.c (revision 11099)
1*11099Ssam /*	tuboot.c	4.1	83/02/16	*/
2*11099Ssam 
3*11099Ssam /*
4*11099Ssam  * VAX tu58 console cassette boot block
5*11099Ssam  *
6*11099Ssam  * Thomas Ferrin  27oct82
7*11099Ssam  *
8*11099Ssam  * Reads a program from a tp directory on tape
9*11099Ssam  * and executes it.  Program must be stripped of
10*11099Ssam  * the header and is loaded ``bits as is''.
11*11099Ssam  * You can return to this loader via ``ret'' as
12*11099Ssam  * you are called ``calls $0,ent''.
13*11099Ssam  */
14*11099Ssam 	.set	RELOC,0x70000
15*11099Ssam /* a.out defines */
16*11099Ssam 	.set	HDRSIZ,040	/* size of file header for VAX */
17*11099Ssam 	.set	MAGIC,0410	/* file type id in header */
18*11099Ssam 	.set	TSIZ,4		/* text size */
19*11099Ssam 	.set	DSIZ,8		/* data size */
20*11099Ssam 	.set	BSIZ,12		/* bss size */
21*11099Ssam 	.set	TENT,024	/* task header entry loc */
22*11099Ssam /* tp directory definitions */
23*11099Ssam /*	.set	DIRBLK,8	/* tp directory starts at block 8 */
24*11099Ssam 	.set	DIRBLK,1	/* tp directory starts at block 1 */
25*11099Ssam 	.set	FILSIZ,38	/* tp direc offset for file size */
26*11099Ssam 	.set	BNUM,44		/* tp dir offset for start block no. */
27*11099Ssam 	.set	ENTSIZ,64	/* size of 1 TP dir entry, bytes */
28*11099Ssam 	.set	PTHSIZ,32	/* size of TP path name, bytes */
29*11099Ssam 	.set	BLKSIZ,512	/* tape block size, bytes */
30*11099Ssam 	.set	NUMDIR,24	/* no. of dir blocks on tape */
31*11099Ssam 	.set	ENTBLK,8	/* no. of dir entries per tape block */
32*11099Ssam /* processor registers and bits */
33*11099Ssam 	.set	RXCS,32
34*11099Ssam 	.set	RXDB,33
35*11099Ssam 	.set	TXCS,34
36*11099Ssam 	.set	TXDB,35
37*11099Ssam 	.set	RXCS_DONE,0x80
38*11099Ssam 	.set	TXCS_RDY,0x80
39*11099Ssam 	.set	TXCS_pr,7	/* bit position of TXCS ready bit */
40*11099Ssam 	.set	RXCS_pd,7	/* bit position of RXCS done bit */
41*11099Ssam /* console storage registers and bits */
42*11099Ssam 	.set	CSRS,0x1c
43*11099Ssam 	.set	CSRD,0x1d
44*11099Ssam 	.set	CSTS,0x1e
45*11099Ssam 	.set	CSTD,0x1f
46*11099Ssam /* TU commands and bits */
47*11099Ssam 	.set	TU_BREAK,1
48*11099Ssam 	.set	TU_INIT,4
49*11099Ssam 	.set	TU_CONTINUE,16
50*11099Ssam 	.set	TU_READY,7	/* bit position of CSRS ready bit */
51*11099Ssam 	.set	TU_PACKETLEN,8	/* length of readcom block */
52*11099Ssam /* local stack variables */
53*11099Ssam 	.set	tapa,-4		/* desired tape addr */
54*11099Ssam 	.set	name,-8-PTHSIZ	/* operator-typed file name */
55*11099Ssam /* ===== */
56*11099Ssam 
57*11099Ssam /* initialization */
58*11099Ssam init:
59*11099Ssam 	.word	0 		/* entry mask for dec monitor */
60*11099Ssam 	nop;nop;nop;nop;nop	/* some no-ops for 750 boot rom to skip */
61*11099Ssam 	nop;nop;nop;nop;nop
62*11099Ssam 	movl	$RELOC,fp	/* core loc to which to move this program */
63*11099Ssam 	addl3	$name,fp,sp	/* set stack pointer; leave room for locals */
64*11099Ssam 	clrl	r0
65*11099Ssam 1:
66*11099Ssam 	movc3	$end,(r0),(fp)	/* move boot up to relocated position */
67*11099Ssam 	jmp	start+RELOC
68*11099Ssam 
69*11099Ssam start:
70*11099Ssam /* init tu58 */
71*11099Ssam 	mtpr	$TU_BREAK,$CSTS		/* set break condition */
72*11099Ssam 	clrl	r2		/* nulls */
73*11099Ssam 	bsbw	xmit2		/* wait 2 character times */
74*11099Ssam 	mfpr	$CSRD,r2	/* clear receive buffer */
75*11099Ssam 	movzwl	$TU_INIT|(TU_INIT<<8),r2	/* load 2 INIT opcodes */
76*11099Ssam 	bsbw	xmit2		/* xmit 'em */
77*11099Ssam 1:
78*11099Ssam 	mfpr	$CSRD,r7	/* get recv data */
79*11099Ssam 	cmpb	r7,$TU_CONTINUE		/* is it a continue flag? */
80*11099Ssam 	bneq	1b		/* nope, look more */
81*11099Ssam 
82*11099Ssam 	movab	name(fp),r4		/* start of filename storage */
83*11099Ssam 	movzbl	$'=,r0			/* prompt character */
84*11099Ssam 	bsbw	putc			/* output char to main console */
85*11099Ssam 
86*11099Ssam /* read in a file name */
87*11099Ssam 	movl	r4,r1			/* loc at which to store file name */
88*11099Ssam nxtc:
89*11099Ssam 	bsbw	getc			/* get input char's in file name */
90*11099Ssam 	cmpb	r0,$012			/* terminator ? */
91*11099Ssam 	beql	nullc
92*11099Ssam 	movb	r0,(r1)+
93*11099Ssam 	brb	nxtc
94*11099Ssam nullc:
95*11099Ssam 	subl3	r4,r1,r9		/* size of path name */
96*11099Ssam 	beql	start			/* dumb operator */
97*11099Ssam 	clrb	(r1)+
98*11099Ssam 	incl	r9
99*11099Ssam 
100*11099Ssam /* user-specified tp filename has been stored at name(fp) */
101*11099Ssam /* read in entire tp directory contents into low core */
102*11099Ssam dirred:
103*11099Ssam 	movl	$DIRBLK,tapa(fp)	/* tp directory starts at block DIRBLK */
104*11099Ssam 	movl	$(NUMDIR*BLKSIZ),r6	/* no. bytes in total dir */
105*11099Ssam 	bsbw	taper			/* read no. bytes indicated */
106*11099Ssam 
107*11099Ssam /* search entire directory for user-specified file name */
108*11099Ssam 	clrl	r5			/* dir buff loc = 0 */
109*11099Ssam nxtdir:
110*11099Ssam 	cmpc3	r9,(r5),(r4)		/* see if dir entry matches filename */
111*11099Ssam 	beql	fndfil			/* found match */
112*11099Ssam 	acbl	$NUMDIR*BLKSIZ-1,$ENTSIZ,r5,nxtdir
113*11099Ssam 					/* see if done with tp dir */
114*11099Ssam 	brw	start			/* entry not in directory; start over */
115*11099Ssam 
116*11099Ssam /* found desired tp dir entry */
117*11099Ssam fndfil:
118*11099Ssam 	movzwl	BNUM(r5),tapa(fp)	/* start block no., 2 bytes */
119*11099Ssam 	addl2	$DIRBLK-1,tapa(fp)	/* skip boot block(s) */
120*11099Ssam 	movzwl	FILSIZ(r5),r6		/* low 2 bytes file size */
121*11099Ssam 	insv	FILSIZ-1(r5),$16,$8,r6	/* file size, high byte */
122*11099Ssam 	cmpl	r6,$RELOC-512		/* check if file fits below stack */
123*11099Ssam 	blss	filok 			/* file o.k. */
124*11099Ssam 	brw	start			/* file too large */
125*11099Ssam 
126*11099Ssam /* time to read in desired file from tape */
127*11099Ssam filok:
128*11099Ssam 	movl	r6,r5			/* start of bss space */
129*11099Ssam 	bsbb	taper
130*11099Ssam 	bsbb	rew
131*11099Ssam 
132*11099Ssam /* clear core */
133*11099Ssam 	subl3	r5,$RELOC-4,r0		/* no. bytes to clear */
134*11099Ssam 1:
135*11099Ssam 	clrb	(r5)+
136*11099Ssam 	sobgtr	r0,1b
137*11099Ssam 
138*11099Ssam /* time to jump to start of file & execute */
139*11099Ssam 	addl3	$20,fp,ap
140*11099Ssam 	clrl	r5
141*11099Ssam 	calls	$0,(r5)
142*11099Ssam bad:
143*11099Ssam 	brw	start
144*11099Ssam 
145*11099Ssam /* rewind tape */
146*11099Ssam rew:
147*11099Ssam 	movb	$5,readcom+2	/* position opcode */
148*11099Ssam 	clrl	tapa(fp)	/* block 0 */
149*11099Ssam 	clrl	r6		/* 0 bytes */
150*11099Ssam 	bsbb	taper
151*11099Ssam 	movb	$2,readcom+2	/* read opcode */
152*11099Ssam 	rsb
153*11099Ssam 
154*11099Ssam /* read (r6) bytes from tapa(fp) into loc 0 */
155*11099Ssam taper:
156*11099Ssam 	clrl	r8		/* initialize checksum */
157*11099Ssam 	movab	readcom,r0	/* read command packet addr */
158*11099Ssam 	movzbl	$TU_PACKETLEN/2,r1	/* size of readcom block */
159*11099Ssam 1:
160*11099Ssam 	movzwl	(r0)+,r2	/* get 2 chars from block */
161*11099Ssam 	bsbb	xmit		/* xmit and update ckecksum */
162*11099Ssam 	sobgtr	r1,1b		/* loop if more */
163*11099Ssam 
164*11099Ssam 	/* now do variable part of packet */
165*11099Ssam 	movl	r6,r2		/* byte count */
166*11099Ssam 	bsbb	xmit
167*11099Ssam 	movzwl	tapa(fp),r2	/* starting block number */
168*11099Ssam 	bsbb	xmit
169*11099Ssam 	movzwl	r8,r2		/* accumulated ckecksum */
170*11099Ssam 	bsbb	xmit
171*11099Ssam 
172*11099Ssam 	/* collect read packet from device */
173*11099Ssam 	clrl	r0		/* starting addr */
174*11099Ssam 1:
175*11099Ssam 	bsbb	recv2		/* get 2 packet characters */
176*11099Ssam 	decb	r2		/* data packet? */
177*11099Ssam 	bneq	1f		/* branch on end of data */
178*11099Ssam 	movzbl	r1,r8		/* get byte count of packet */
179*11099Ssam 
180*11099Ssam 	/* read data into memory */
181*11099Ssam 2:
182*11099Ssam 	bsbb	recv1		/* get a char */
183*11099Ssam 	movb	r1,(r0)+	/* stuff into memory */
184*11099Ssam 	sobgtr	r8,2b		/* loop if more */
185*11099Ssam 	bsbb	recv2		/* skip checksum */
186*11099Ssam 	brb	1b		/* read next packet */
187*11099Ssam 
188*11099Ssam 	/* end of data xfer; check for errors */
189*11099Ssam 1:
190*11099Ssam 	subl2	r6,r0		/* all bytes xfered? */
191*11099Ssam 	bneq	9f		/* nope, error */
192*11099Ssam 	bsbb	recv2		/* get success code */
193*11099Ssam 	tstl	r1		/* error in read? */
194*11099Ssam 	blss	9f		/* branch if status error */
195*11099Ssam 	movl	$5,r0
196*11099Ssam 1:
197*11099Ssam 	bsbb	recv2		/* discard 10 bytes */
198*11099Ssam 	sobgtr	r0,1b
199*11099Ssam 	rsb
200*11099Ssam 
201*11099Ssam 	/* fatal error */
202*11099Ssam 9:
203*11099Ssam 	movab	ermsg,r1
204*11099Ssam 1:
205*11099Ssam 	movb	(r1)+,r0
206*11099Ssam 	beql	bad
207*11099Ssam 	bsbb	putc
208*11099Ssam 	brb	1b
209*11099Ssam 
210*11099Ssam 	/* update checksum in r8 and xmit 2 characters */
211*11099Ssam xmit:
212*11099Ssam 	addw2	r2,r8		/* update checksum */
213*11099Ssam 	bcc	xmit2		/* branch if no overflow */
214*11099Ssam 	incw	r8		/* add  in carry */
215*11099Ssam 
216*11099Ssam 	/* send the 2 characters contained in r2 */
217*11099Ssam xmit2:
218*11099Ssam 	bsbb	1f		/* xmit one of 'em */
219*11099Ssam 	ashl	$-8,r2,r2	/* get next char */
220*11099Ssam 				/* fall into... */
221*11099Ssam 1:
222*11099Ssam 	mfpr	$CSTS,r7	/* get xmit status */
223*11099Ssam 	bbc	$TU_READY,r7,1b	/* loop until ready */
224*11099Ssam 	mtpr	r2,$CSTD	/* send char */
225*11099Ssam 	rsb
226*11099Ssam 
227*11099Ssam 	/* receive 2 characters, return in r2 and r1 */
228*11099Ssam recv2:
229*11099Ssam 	bsbb	recv1		/* recv one of 'em */
230*11099Ssam 				/* fall into... */
231*11099Ssam 
232*11099Ssam 	/* receive 1 character */
233*11099Ssam recv1:
234*11099Ssam 	movzbl	r1,r2		/* save previous byte */
235*11099Ssam 1:
236*11099Ssam 	mfpr	$CSRS,r7	/* get recv status */
237*11099Ssam 	bbc	$TU_READY,r7,1b	/* loop until ready */
238*11099Ssam 	mfpr	$CSRD,r1	/* get char */
239*11099Ssam 	blss	9b		/* branch on recv error */
240*11099Ssam 	rsb
241*11099Ssam 
242*11099Ssam getc:
243*11099Ssam 	mfpr	$RXCS,r0
244*11099Ssam 	bbc	$RXCS_pd,r0,getc	/* receiver ready ? */
245*11099Ssam 	mfpr	$RXDB,r0
246*11099Ssam 	extzv	$0,$7,r0,r0
247*11099Ssam 	cmpb	r0,$015
248*11099Ssam 	bneq	putc			/* echo and return */
249*11099Ssam 	bsbb	putc			/* carriage return */
250*11099Ssam 	movb	$0,r0
251*11099Ssam 	bsbb	putc			/* delay */
252*11099Ssam 	movb	$012,r0			/* send line feed and return */
253*11099Ssam putc:
254*11099Ssam 	mfpr	$TXCS,r2
255*11099Ssam 	bbc	$TXCS_pr,r2,putc	/* transmitter ready ? */
256*11099Ssam 	extzv	$0,$7,r0,r0
257*11099Ssam 	mtpr	r0,$TXDB
258*11099Ssam 	rsb
259*11099Ssam 
260*11099Ssam 	.align	2
261*11099Ssam readcom:
262*11099Ssam 	.byte	2	/* command packet flag */
263*11099Ssam 	.byte	10	/* number of bytes in message */
264*11099Ssam 	.byte	2	/* tu read opcode */
265*11099Ssam 	.byte	0	/* modifier */
266*11099Ssam 	.byte	0	/* unit number */
267*11099Ssam 	.byte	0	/* switches */
268*11099Ssam 	.word	0	/* sequence number */
269*11099Ssam 			/* byte count and block number follow */
270*11099Ssam 
271*11099Ssam ermsg:
272*11099Ssam 	.asciz	"tu58 err\r\n"
273*11099Ssam end:
274