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