must set r11 to insure boot asks for name
[unix-history] / usr / src / sys / vax / mdec / tuboot.c
CommitLineData
66fe6398 1/* tuboot.c 4.6 83/08/01 */
1aa3420e
SL
2
3/*
4 * VAX tu58 console cassette boot block
5 *
61deda4c 6 * Helge Skrivervik CSRG/UCB 18jun83
1aa3420e 7 *
61deda4c
HS
8 * Reads a program from a rt-11 directory on tape
9 * and executes it. Programs must be stripped of
1aa3420e
SL
10 * the header and is loaded ``bits as is''.
11 * You can return to this loader via ``ret'' as
12 * you are called ``calls $0,ent''.
61deda4c
HS
13 * Error checking and recovery is almost nonexistant
14 * due to the severe space constraints.
15 *
16 * NOTE: Any changes to this program are likely to
17 * bring the size over 512 bytes ....
18 *
19 * Based on tp format bootstrap originally written by Thomas Ferrin.
20 *
1aa3420e 21 */
61deda4c 22 .set CTABLE,0x400 /* where to load the rad50 cnv table */
1aa3420e 23 .set RELOC,0x70000
3fa0fcf5
HS
24/* rt-11 directory definitions */
25 .set DIRBLK,6 /* rt-11 directory starts at block 6 */
26 .set FILSIZ,8 /* rt-11 direc entry offset for file size */
27 .set ENTSIZ,14 /* size of 1 rt-11 dir entry, bytes */
1aa3420e 28 .set BLKSIZ,512 /* tape block size, bytes */
3fa0fcf5 29 .set NUMDIR,2 /* no. of dir blocks on tape */
61deda4c 30 .set FNSIZ,8 /* size of rad50 filename + 2 */
3fa0fcf5 31 .set NAME,2 /* direc entry offset for filename */
61deda4c 32 .set STATUS,1 /* direc entry offset for entry status */
3fa0fcf5
HS
33/* rt-11 directory entry status */
34 .set RT_ESEG,8 /* end of directory segment */
35 .set RT_NULL,2 /* empty entry */
36 .set RT_FILE,4 /* valid file entry */
1aa3420e
SL
37/* processor registers and bits */
38 .set RXCS,32
39 .set RXDB,33
40 .set TXCS,34
41 .set TXDB,35
42 .set RXCS_DONE,0x80
43 .set TXCS_RDY,0x80
44 .set TXCS_pr,7 /* bit position of TXCS ready bit */
45 .set RXCS_pd,7 /* bit position of RXCS done bit */
46/* console storage registers and bits */
47 .set CSRS,0x1c
48 .set CSRD,0x1d
49 .set CSTS,0x1e
50 .set CSTD,0x1f
51/* TU commands and bits */
52 .set TU_BREAK,1
53 .set TU_INIT,4
54 .set TU_CONTINUE,16
55 .set TU_READY,7 /* bit position of CSRS ready bit */
56 .set TU_PACKETLEN,8 /* length of readcom block */
57/* local stack variables */
66fe6398
SL
58 .set ext,-4 /* file ext. */
59 .set name,-20 /* 12 bytes for full name */
60 .set rt_name,-20-FNSIZ /* rad50 file name */
61/* reboot flags for boot */
62 .set RB_ASK,3 /* ask name and come up single user */
1aa3420e 63
3fa0fcf5
HS
64/*
65 * Initialization.
66 */
1aa3420e
SL
67init:
68 .word 0 /* entry mask for dec monitor */
69 nop;nop;nop;nop;nop /* some no-ops for 750 boot rom to skip */
70 nop;nop;nop;nop;nop
71 movl $RELOC,fp /* core loc to which to move this program */
61deda4c 72 addl3 $rt_name,fp,sp /* set stack pointer; leave room for locals */
1aa3420e
SL
73 clrl r0
741:
75 movc3 $end,(r0),(fp) /* move boot up to relocated position */
76 jmp start+RELOC
77
78start:
1aa3420e 79 mtpr $TU_BREAK,$CSTS /* set break condition */
3fa0fcf5
HS
80 clrl r2 /* nulls */
81 bsbw xmit2 /* wait 2 character times */
82 mfpr $CSRD,r2 /* clear receive buffer */
1aa3420e 83 movzwl $TU_INIT|(TU_INIT<<8),r2 /* load 2 INIT opcodes */
3fa0fcf5 84 bsbw xmit2 /* xmit 'em */
1aa3420e 851:
3fa0fcf5 86 mfpr $CSRD,r7 /* get recv data */
1aa3420e 87 cmpb r7,$TU_CONTINUE /* is it a continue flag? */
3fa0fcf5 88 bneq 1b /* nope, look more */
1aa3420e
SL
89
90 movab name(fp),r4 /* start of filename storage */
61deda4c
HS
91 clrq (r4) /* init name field */
92 clrq name+8(fp)
93 clrq rt_name(fp) /* init rad50 filename */
1aa3420e
SL
94 movzbl $'=,r0 /* prompt character */
95 bsbw putc /* output char to main console */
96
61deda4c
HS
97/*
98 * Read in a file name from console.
99 */
1aa3420e
SL
100 movl r4,r1 /* loc at which to store file name */
101nxtc:
102 bsbw getc /* get input char's in file name */
103 cmpb r0,$012 /* terminator ? */
104 beql nullc
105 movb r0,(r1)+
106 brb nxtc
107nullc:
61deda4c 108 cmpl r4,r1
3fa0fcf5
HS
109 beql start /* restart if empty string */
110 clrb (r1) /* add null byte at end */
1aa3420e 111
3fa0fcf5 112/*
61deda4c
HS
113 * User-specified filename has been stored at name(fp),
114 * read the entire directory contents into low core.
3fa0fcf5 115 */
1aa3420e 116dirred:
3fa0fcf5 117 movl $DIRBLK,r10 /* directory starts at block DIRBLK */
1aa3420e 118 movl $(NUMDIR*BLKSIZ),r6 /* no. bytes in total dir */
3fa0fcf5 119 clrl r11 /* start address */
1aa3420e 120 bsbw taper /* read no. bytes indicated */
3fa0fcf5
HS
121/*
122 * Read in the character conversion table which reside in block 1
61deda4c
HS
123 * (the second block) on the cassette. Place it after the directory
124 * on low core (from 0x400).
3fa0fcf5 125 */
61deda4c 126 movl $1,r10 /* block number */
3fa0fcf5 127 movl $BLKSIZ,r6 /* read one block */
3fa0fcf5 128 bsbw taper
1aa3420e 129
3fa0fcf5
HS
130/*
131 * Convert the ascii filename to rad50.
61deda4c 132 * R4 still points to name(fp)
3fa0fcf5 133 */
3fa0fcf5
HS
134 movl $6,r3 /* max length of filename */
1351:
136 cmpb $'.,(r4)+ /* look for '.' */
61deda4c 137 beql 1f
3fa0fcf5 138 sobgtr r3,1b
61deda4c
HS
139 incl r4 /* point past '.' if ext is present */
1401:
3fa0fcf5
HS
141 clrb -1(r4) /* end name with null */
142 movl $3,r3 /* max length of extension */
143 movab ext(fp),r5 /* place extension here */
1441:
145 movb (r4)+,(r5)+
146 beql 1f /* the string is null terminated */
147 sobgtr r3,1b
1481:
149 movab name(fp),r4
150 movab rt_name(fp),r5 /* ptr to rad50 name */
151 bsbw rad50 /* convert filename */
152 movab ext(fp),r4
153 movab rt_name+4(fp),r5
154 bsbw rad50 /* convert extension */
155
156/*
157 * Search entire directory for user-specified file name.
158 */
159
160 movab rt_name(fp),r4 /* search for this file */
61deda4c
HS
161 movl $10,r5 /* point to first file entry */
162 movzwl -2(r5),r10 /* r10 = block # where files begin */
3fa0fcf5
HS
1632:
164 cmpc3 $6,NAME(r5),(r4) /* see if dir entry matches filename */
1aa3420e 165 beql fndfil /* found match */
3fa0fcf5 1661:
61deda4c 167 addw2 FILSIZ(r5),r10 /* add file length to block pointer */
3fa0fcf5 168 addl2 $ENTSIZ,r5 /* move to next entry */
61deda4c
HS
169# cpmb STATUS(r5),$RT_NULL /* check if deleted file */
170# beql 1b /* not really necessary since deleted entries will fail */
171 /* to compare anyway */
172 cmpb STATUS(r5),$RT_ESEG /* check if end of segment */
3fa0fcf5 173 bneq 2b
1aa3420e
SL
174 brw start /* entry not in directory; start over */
175
3fa0fcf5
HS
176/*
177 * Found desired directory entry
178 */
1aa3420e 179fndfil:
61deda4c 180 /* start block no., 2 bytes in r10 */
3fa0fcf5
HS
181 movzwl FILSIZ(r5),r6 /* file size (blocks) */
182 mull2 $BLKSIZ,r6 /* file size (bytes) */
61deda4c
HS
183 cmpl r6,$RELOC-512 /* check if file fits below stack */
184 blss filok
185 brw start /* file too large */
1aa3420e 186
3fa0fcf5
HS
187/*
188 * Read in desired file from tape.
189 */
1aa3420e
SL
190filok:
191 movl r6,r5 /* start of bss space */
3fa0fcf5 192 clrl r11 /* start address */
1aa3420e 193 bsbb taper
1aa3420e 194
3fa0fcf5
HS
195/*
196 * Clear core.
197 */
1aa3420e
SL
198 subl3 r5,$RELOC-4,r0 /* no. bytes to clear */
1991:
200 clrb (r5)+
201 sobgtr r0,1b
202
3fa0fcf5
HS
203/*
204 * Jump to start of file & execute.
205 */
61deda4c 206 addl3 $20,fp,ap /* ?? */
1aa3420e 207 clrl r5
66fe6398 208 movl $RB_ASK,r11
1aa3420e
SL
209 calls $0,(r5)
210bad:
211 brw start
212
61deda4c
HS
213/*
214 * Read (r6) bytes from block (r10)
215 * into loc (r11).
216 */
1aa3420e 217taper:
3fa0fcf5
HS
218 clrl r8 /* initialize checksum */
219 movab readcom,r0 /* read command packet addr */
1aa3420e
SL
220 movzbl $TU_PACKETLEN/2,r1 /* size of readcom block */
2211:
3fa0fcf5
HS
222 movzwl (r0)+,r2 /* get 2 chars from block */
223 bsbb xmit /* xmit and update ckecksum */
224 sobgtr r1,1b /* loop if more */
1aa3420e 225
61deda4c
HS
226/*
227 * Now do variable part of packet.
228 */
3fa0fcf5 229 movl r6,r2 /* byte count */
1aa3420e 230 bsbb xmit
3fa0fcf5 231 movl r10,r2 /* starting block number */
1aa3420e 232 bsbb xmit
3fa0fcf5 233 movzwl r8,r2 /* accumulated ckecksum */
1aa3420e
SL
234 bsbb xmit
235
61deda4c
HS
236/*
237 * Collect read packet from device.
238 */
1aa3420e 2391:
3fa0fcf5
HS
240 bsbb recv2 /* get 2 packet characters */
241 decb r2 /* data packet? */
242 bneq 1f /* branch on end of data */
243 movzbl r1,r8 /* get byte count of packet */
1aa3420e 244
61deda4c
HS
245/*
246 * Read data into memory.
247 */
1aa3420e 2482:
3fa0fcf5 249 bsbb recv1 /* get a char */
61deda4c 250 movb r1,(r11)+ /* stuff into memory */
3fa0fcf5
HS
251 sobgtr r8,2b /* loop if more */
252 bsbb recv2 /* skip checksum */
253 brb 1b /* read next packet */
1aa3420e 254
61deda4c
HS
255/*
256 * End of data xfer; check for errors.
257 */
1aa3420e 2581:
3fa0fcf5
HS
259 bsbb recv2 /* get success code */
260 tstl r1 /* error in read? */
261 blss 9f /* branch if status error */
1aa3420e
SL
262 movl $5,r0
2631:
3fa0fcf5 264 bsbb recv2 /* discard 10 bytes */
1aa3420e
SL
265 sobgtr r0,1b
266 rsb
267
61deda4c 268/* Fatal error */
1aa3420e
SL
2699:
270 movab ermsg,r1
2711:
272 movb (r1)+,r0
273 beql bad
274 bsbb putc
275 brb 1b
276
61deda4c
HS
277/*
278 * Update checksum in r8 and xmit 2 characters.
279 */
1aa3420e 280xmit:
3fa0fcf5 281 addw2 r2,r8 /* update checksum */
61deda4c 282 adwc $0,r8 /* add in carry */
1aa3420e 283
61deda4c 284/* send the 2 characters contained in r2 */
1aa3420e 285xmit2:
3fa0fcf5
HS
286 bsbb 1f /* xmit one of 'em */
287 ashl $-8,r2,r2 /* get next char */
288 /* fall into... */
1aa3420e 2891:
3fa0fcf5
HS
290 mfpr $CSTS,r7 /* get xmit status */
291 bbc $TU_READY,r7,1b /* loop until ready */
292 mtpr r2,$CSTD /* send char */
1aa3420e
SL
293 rsb
294
61deda4c
HS
295/*
296 * Receive 2 characters, return in r2 and r1.
297 */
1aa3420e 298recv2:
3fa0fcf5
HS
299 bsbb recv1 /* recv one of 'em */
300 /* fall into... */
1aa3420e 301
61deda4c
HS
302/*
303 * Receive 1 character.
304 */
1aa3420e 305recv1:
3fa0fcf5 306 movzbl r1,r2 /* save previous byte */
1aa3420e 3071:
3fa0fcf5
HS
308 mfpr $CSRS,r7 /* get recv status */
309 bbc $TU_READY,r7,1b /* loop until ready */
310 mfpr $CSRD,r1 /* get char */
2fb59fbf 311 blss 9b /* branch on recv error */
1aa3420e
SL
312 rsb
313
314getc:
315 mfpr $RXCS,r0
316 bbc $RXCS_pd,r0,getc /* receiver ready ? */
317 mfpr $RXDB,r0
7107ab6e 318 extzv $0,$7,r0,r0
1aa3420e
SL
319 cmpb r0,$015
320 bneq putc /* echo and return */
321 bsbb putc /* carriage return */
3fa0fcf5
HS
322# movb $0,r0
323# bsbb putc /* delay */
1aa3420e
SL
324 movb $012,r0 /* send line feed and return */
325putc:
326 mfpr $TXCS,r2
327 bbc $TXCS_pr,r2,putc /* transmitter ready ? */
1aa3420e
SL
328 mtpr r0,$TXDB
329 rsb
330
3fa0fcf5
HS
331/*
332 * Convert the filename given from the console
333 * to radix 50 (rt-11) format.
334 */
335rad50:
61deda4c 336 clrw r1
3fa0fcf5
HS
337 bsbb getb50 /* get next ascii byte, exit if null */
338 mull3 $03100,r0,r1
339 bsbb getb50
340 mull3 $050,r0,r2
341 addl2 r2,r1
342 bsbb getb50
343 addl2 r0,r1 /* last byte, just add it in */
344 movw r1,(r5)+ /* save result */
61deda4c 345 brb rad50
3fa0fcf5
HS
346
347getb50:
348 movzbl (r4)+,r0 /* get next ascii byte */
349 beql 1f /* if zero: end of string */
61deda4c 350 movzbl CTABLE(r0),r0 /* and get the r50 byte from the table*/
3fa0fcf5
HS
351 rsb
3521:
353 tstl (sp)+ /* we're through, get back to where */
354 /* rad50 was called */
355 movw r1,(r5) /* but first save the result */
356 rsb
357
1aa3420e
SL
358 .align 2
359readcom:
3fa0fcf5
HS
360 .byte 2 /* command packet flag */
361 .byte 10 /* number of bytes in message */
362 .byte 2 /* tu read opcode */
363 .byte 0 /* modifier */
364 .byte 0 /* unit number */
365 .byte 0 /* switches */
366 .word 0 /* sequence number */
367 /* byte count and block number follow */
1aa3420e
SL
368
369ermsg:
66fe6398 370 .asciz "tuerr\r\n"
1aa3420e 371end:
2fb59fbf
HS
372
373/*
374 * Ascii to rad 50 conversion table,
375 * stored on the second block on the cassette
376 *
377 * NOTE: Always make sure this table ends up
378 * starting at byte 512!!!!
379 */
380 .align 2
381 .data 2
382 .long 0x1d1d1d1d
383 .long 0x1d1d1d1d
384 .long 0x1d1d1d1d
385 .long 0x1d1d1d1d
386 .long 0x1d1d1d1d
387 .long 0x1d1d1d1d
388 .long 0x1d1d1d1d
389 .long 0x1d1d1d1d
390 .long 0x1d1d1d00
391 .long 0x1d1d1d1b
392 .long 0x1d1d1d1d
393 .long 0x1d1c1d1d
394 .long 0x21201f1e
395 .long 0x25242322
396 .long 0x1d1d2726
397 .long 0x1d1d1d1d
398 .long 0x302011d
399 .long 0x7060504
400 .long 0xb0a0908
401 .long 0xf0e0d0c
402 .long 0x13121110
403 .long 0x17161514
404 .long 0x1d1a1918
405 .long 0x1d1d1d1d
406 .long 0x302011d
407 .long 0x7060504
408 .long 0xb0a0908
409 .long 0xf0e0d0c
410 .long 0x13121110
411 .long 0x17161514
412 .long 0x1d1a1918
413 .long 0x1d1d1d1d
414 .long 0x1d1d1d1d
415 .long 0x1d1d1d1d
416 .long 0x1d1d1d1d
417 .long 0x1d1d1d1d
418 .long 0x1d1d1d1d
419 .long 0x1d1d1d1d
420 .long 0x1d1d1d1d
421 .long 0x1d1d1d1d
422 .long 0x1d1d1d00
423 .long 0x1d1d1d1b
424 .long 0x1d1d1d1d
425 .long 0x1d1c1d1d
426 .long 0x21201f1e
427 .long 0x25242322
428 .long 0x1d1d2726
429 .long 0x1d1d1d1d
430 .long 0x302011d
431 .long 0x7060504
432 .long 0xb0a0908
433 .long 0xf0e0d0c
434 .long 0x13121110
435 .long 0x17161514
436 .long 0x1d1a1918
437 .long 0x1d1d1d1d
438 .long 0x302011d
439 .long 0x7060504
440 .long 0xb0a0908
441 .long 0xf0e0d0c
442 .long 0x13121110
443 .long 0x17161514
444 .long 0x1d1a1918
445 .long 0x1d1d1d
446 .data