inline expand distpte() in Fastreclaim
[unix-history] / usr / src / sys / vax / mdec / tuboot.c
CommitLineData
3fa0fcf5 1/* tuboot.s 4.1 83/02/16 */
1aa3420e
SL
2
3/*
4 * VAX tu58 console cassette boot block
5 *
6 * Thomas Ferrin 27oct82
7 *
8 * Reads a program from a tp directory on tape
9 * and executes it. Program must be stripped of
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''.
3fa0fcf5
HS
13 *
14 * Helge Skrivervik CSRG/UCB 18jun83
15 * Changed to use rt-11 format directory & files
16 * instead of tp format
1aa3420e
SL
17 */
18 .set RELOC,0x70000
19/* a.out defines */
20 .set HDRSIZ,040 /* size of file header for VAX */
21 .set MAGIC,0410 /* file type id in header */
22 .set TSIZ,4 /* text size */
23 .set DSIZ,8 /* data size */
24 .set BSIZ,12 /* bss size */
25 .set TENT,024 /* task header entry loc */
3fa0fcf5
HS
26/* rt-11 directory definitions */
27 .set DIRBLK,6 /* rt-11 directory starts at block 6 */
28 .set FILSIZ,8 /* rt-11 direc entry offset for file size */
29 .set ENTSIZ,14 /* size of 1 rt-11 dir entry, bytes */
1aa3420e 30 .set BLKSIZ,512 /* tape block size, bytes */
3fa0fcf5
HS
31 .set NUMDIR,2 /* no. of dir blocks on tape */
32 .set RT_FNSIZ,8 /* size of rad50 filename + 2 */
33 .set NAME,2 /* direc entry offset for filename */
34 .set RT_STAT,1 /* direc entry offset for entry status */
35/* rt-11 directory entry status */
36 .set RT_ESEG,8 /* end of directory segment */
37 .set RT_NULL,2 /* empty entry */
38 .set RT_FILE,4 /* valid file entry */
1aa3420e
SL
39/* processor registers and bits */
40 .set RXCS,32
41 .set RXDB,33
42 .set TXCS,34
43 .set TXDB,35
44 .set RXCS_DONE,0x80
45 .set TXCS_RDY,0x80
46 .set TXCS_pr,7 /* bit position of TXCS ready bit */
47 .set RXCS_pd,7 /* bit position of RXCS done bit */
48/* console storage registers and bits */
49 .set CSRS,0x1c
50 .set CSRD,0x1d
51 .set CSTS,0x1e
52 .set CSTD,0x1f
53/* TU commands and bits */
54 .set TU_BREAK,1
55 .set TU_INIT,4
56 .set TU_CONTINUE,16
57 .set TU_READY,7 /* bit position of CSRS ready bit */
58 .set TU_PACKETLEN,8 /* length of readcom block */
59/* local stack variables */
3fa0fcf5
HS
60 .set ext,-4 /* file ext. */
61 .set name,-20 /* 12 bytes for full name */
62 .set rt_name,-20-RT_FNSIZ /* rad50 file name */
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 */
72 addl3 $name,fp,sp /* set stack pointer; leave room for locals */
73 clrl r0
741:
75 movc3 $end,(r0),(fp) /* move boot up to relocated position */
76 jmp start+RELOC
77
78start:
79/* init tu58 */
80 mtpr $TU_BREAK,$CSTS /* set break condition */
3fa0fcf5
HS
81 clrl r2 /* nulls */
82 bsbw xmit2 /* wait 2 character times */
83 mfpr $CSRD,r2 /* clear receive buffer */
1aa3420e 84 movzwl $TU_INIT|(TU_INIT<<8),r2 /* load 2 INIT opcodes */
3fa0fcf5 85 bsbw xmit2 /* xmit 'em */
1aa3420e 861:
3fa0fcf5 87 mfpr $CSRD,r7 /* get recv data */
1aa3420e 88 cmpb r7,$TU_CONTINUE /* is it a continue flag? */
3fa0fcf5 89 bneq 1b /* nope, look more */
1aa3420e 90
3fa0fcf5 91 clrq rt_name(fp) /* init rad50 filename */
1aa3420e
SL
92 movab name(fp),r4 /* start of filename storage */
93 movzbl $'=,r0 /* prompt character */
94 bsbw putc /* output char to main console */
95
96/* read in a file name */
97 movl r4,r1 /* loc at which to store file name */
98nxtc:
99 bsbw getc /* get input char's in file name */
100 cmpb r0,$012 /* terminator ? */
101 beql nullc
102 movb r0,(r1)+
103 brb nxtc
104nullc:
105 subl3 r4,r1,r9 /* size of path name */
3fa0fcf5
HS
106 beql start /* restart if empty string */
107 clrb (r1) /* add null byte at end */
108 incl r9 /* and fix length */
1aa3420e 109
3fa0fcf5
HS
110/*
111 * user-specified filename has been stored at name(fp)
112 * read in entire directory contents into low core
113 */
1aa3420e 114dirred:
3fa0fcf5 115 movl $DIRBLK,r10 /* directory starts at block DIRBLK */
1aa3420e 116 movl $(NUMDIR*BLKSIZ),r6 /* no. bytes in total dir */
3fa0fcf5 117 clrl r11 /* start address */
1aa3420e 118 bsbw taper /* read no. bytes indicated */
3fa0fcf5
HS
119/*
120 * Read in the character conversion table which reside in block 1
121 * (the second block) on the cassette.
122 */
123 movl $1,r10 /* start block */
124 movl $BLKSIZ,r6 /* read one block */
125 movl 0x400,r11 /* place it after the directory */
126 bsbw taper
1aa3420e 127
3fa0fcf5
HS
128/*
129 * Convert the ascii filename to rad50.
130 */
131 movab name(fp),r4 /* ptr to ascii name */
132 movl $6,r3 /* max length of filename */
1331:
134 cmpb $'.,(r4)+ /* look for '.' */
135 sobgtr r3,1b
136 clrb -1(r4) /* end name with null */
137 movl $3,r3 /* max length of extension */
138 movab ext(fp),r5 /* place extension here */
1391:
140 movb (r4)+,(r5)+
141 beql 1f /* the string is null terminated */
142 sobgtr r3,1b
1431:
144 movab name(fp),r4
145 movab rt_name(fp),r5 /* ptr to rad50 name */
146 bsbw rad50 /* convert filename */
147 movab ext(fp),r4
148 movab rt_name+4(fp),r5
149 bsbw rad50 /* convert extension */
150
151/*
152 * Search entire directory for user-specified file name.
153 */
154
155 movab rt_name(fp),r4 /* search for this file */
156 movl $10,r5 /* dir buff loc = 0, point to first */
157 /* file entry */
158 movzwl -2(r5),r3 /* r3 = block # where files begin */
1592:
160 cmpc3 $6,NAME(r5),(r4) /* see if dir entry matches filename */
1aa3420e 161 beql fndfil /* found match */
3fa0fcf5
HS
1621:
163 addw2 FILSIZ(r5),r3 /* add file length to block pointer */
164 addl2 $ENTSIZ,r5 /* move to next entry */
165# cpmb RT_STAT(r5),$RT_NULL /* check if deleted file */
166# beql 1b
167 cmpb RT_STAT(r5),$RT_ESEG /* check if end of segment */
168 bneq 2b
1aa3420e
SL
169 brw start /* entry not in directory; start over */
170
3fa0fcf5
HS
171/*
172 * Found desired directory entry
173 */
1aa3420e 174fndfil:
3fa0fcf5
HS
175 movl r3,r10 /* start block no., 2 bytes */
176 movzwl FILSIZ(r5),r6 /* file size (blocks) */
177 mull2 $BLKSIZ,r6 /* file size (bytes) */
178# cmpl r6,$RELOC-512 /* check if file fits below stack */
179# blss filok
180# brw start /* file too large */
1aa3420e 181
3fa0fcf5
HS
182/*
183 * Read in desired file from tape.
184 */
1aa3420e
SL
185filok:
186 movl r6,r5 /* start of bss space */
3fa0fcf5 187 clrl r11 /* start address */
1aa3420e 188 bsbb taper
3fa0fcf5 189# bsbb rew
1aa3420e 190
3fa0fcf5
HS
191/*
192 * Clear core.
193 */
1aa3420e
SL
194 subl3 r5,$RELOC-4,r0 /* no. bytes to clear */
1951:
196 clrb (r5)+
197 sobgtr r0,1b
198
3fa0fcf5
HS
199/*
200 * Jump to start of file & execute.
201 */
1aa3420e
SL
202 addl3 $20,fp,ap
203 clrl r5
204 calls $0,(r5)
205bad:
206 brw start
207
208/* rewind tape */
3fa0fcf5 209#ifdef notdef
1aa3420e 210rew:
3fa0fcf5
HS
211 movb $5,readcom+2 /* position opcode */
212 clrl r10 /* block 0 */
213 clrl r6 /* 0 bytes */
1aa3420e 214 bsbb taper
3fa0fcf5 215 movb $2,readcom+2 /* read opcode */
1aa3420e 216 rsb
3fa0fcf5 217#endif
1aa3420e 218
3fa0fcf5 219/* read (r6) bytes from (r10) into loc (r11) */
1aa3420e 220taper:
3fa0fcf5
HS
221 clrl r8 /* initialize checksum */
222 movab readcom,r0 /* read command packet addr */
1aa3420e
SL
223 movzbl $TU_PACKETLEN/2,r1 /* size of readcom block */
2241:
3fa0fcf5
HS
225 movzwl (r0)+,r2 /* get 2 chars from block */
226 bsbb xmit /* xmit and update ckecksum */
227 sobgtr r1,1b /* loop if more */
1aa3420e
SL
228
229 /* now do variable part of packet */
3fa0fcf5 230 movl r6,r2 /* byte count */
1aa3420e 231 bsbb xmit
3fa0fcf5 232 movl r10,r2 /* starting block number */
1aa3420e 233 bsbb xmit
3fa0fcf5 234 movzwl r8,r2 /* accumulated ckecksum */
1aa3420e
SL
235 bsbb xmit
236
237 /* collect read packet from device */
3fa0fcf5 238 movl r11,r0 /* starting addr */
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
SL
244
245 /* read data into memory */
2462:
3fa0fcf5
HS
247 bsbb recv1 /* get a char */
248 movb r1,(r0)+ /* stuff into memory */
249 sobgtr r8,2b /* loop if more */
250 bsbb recv2 /* skip checksum */
251 brb 1b /* read next packet */
1aa3420e
SL
252
253 /* end of data xfer; check for errors */
2541:
3fa0fcf5
HS
255 subl2 r6,r0 /* all bytes xfered? */
256 bneq 9f /* nope, error */
257 bsbb recv2 /* get success code */
258 tstl r1 /* error in read? */
259 blss 9f /* branch if status error */
1aa3420e
SL
260 movl $5,r0
2611:
3fa0fcf5 262 bsbb recv2 /* discard 10 bytes */
1aa3420e
SL
263 sobgtr r0,1b
264 rsb
265
266 /* fatal error */
2679:
268 movab ermsg,r1
2691:
270 movb (r1)+,r0
271 beql bad
272 bsbb putc
273 brb 1b
274
275 /* update checksum in r8 and xmit 2 characters */
276xmit:
3fa0fcf5
HS
277 addw2 r2,r8 /* update checksum */
278 bcc xmit2 /* branch if no overflow */
279 incw r8 /* add in carry */
1aa3420e
SL
280
281 /* send the 2 characters contained in r2 */
282xmit2:
3fa0fcf5
HS
283 bsbb 1f /* xmit one of 'em */
284 ashl $-8,r2,r2 /* get next char */
285 /* fall into... */
1aa3420e 2861:
3fa0fcf5
HS
287 mfpr $CSTS,r7 /* get xmit status */
288 bbc $TU_READY,r7,1b /* loop until ready */
289 mtpr r2,$CSTD /* send char */
1aa3420e
SL
290 rsb
291
292 /* receive 2 characters, return in r2 and r1 */
293recv2:
3fa0fcf5
HS
294 bsbb recv1 /* recv one of 'em */
295 /* fall into... */
1aa3420e
SL
296
297 /* receive 1 character */
298recv1:
3fa0fcf5 299 movzbl r1,r2 /* save previous byte */
1aa3420e 3001:
3fa0fcf5
HS
301 mfpr $CSRS,r7 /* get recv status */
302 bbc $TU_READY,r7,1b /* loop until ready */
303 mfpr $CSRD,r1 /* get char */
304# blss 9b /* branch on recv error */
1aa3420e
SL
305 rsb
306
307getc:
308 mfpr $RXCS,r0
309 bbc $RXCS_pd,r0,getc /* receiver ready ? */
310 mfpr $RXDB,r0
3fa0fcf5 311 movzbl r0,r0
1aa3420e
SL
312 cmpb r0,$015
313 bneq putc /* echo and return */
314 bsbb putc /* carriage return */
3fa0fcf5
HS
315# movb $0,r0
316# bsbb putc /* delay */
1aa3420e
SL
317 movb $012,r0 /* send line feed and return */
318putc:
319 mfpr $TXCS,r2
320 bbc $TXCS_pr,r2,putc /* transmitter ready ? */
1aa3420e
SL
321 mtpr r0,$TXDB
322 rsb
323
3fa0fcf5
HS
324/*
325 * Convert the filename given from the console
326 * to radix 50 (rt-11) format.
327 */
328rad50:
329 movl $0x400,r6 /* address of conversion table */
3301:
331 bsbb getb50 /* get next ascii byte, exit if null */
332 mull3 $03100,r0,r1
333 bsbb getb50
334 mull3 $050,r0,r2
335 addl2 r2,r1
336 bsbb getb50
337 addl2 r0,r1 /* last byte, just add it in */
338 movw r1,(r5)+ /* save result */
339 brb 1b
340
341getb50:
342 movzbl (r4)+,r0 /* get next ascii byte */
343 beql 1f /* if zero: end of string */
344 addl2 r6,r0 /* calculate conversion table address */
345 movzbl (r0),r0 /* and get the r50 byte from the table*/
346 rsb
3471:
348 tstl (sp)+ /* we're through, get back to where */
349 /* rad50 was called */
350 movw r1,(r5) /* but first save the result */
351 rsb
352
1aa3420e
SL
353 .align 2
354readcom:
3fa0fcf5
HS
355 .byte 2 /* command packet flag */
356 .byte 10 /* number of bytes in message */
357 .byte 2 /* tu read opcode */
358 .byte 0 /* modifier */
359 .byte 0 /* unit number */
360 .byte 0 /* switches */
361 .word 0 /* sequence number */
362 /* byte count and block number follow */
1aa3420e
SL
363
364ermsg:
365 .asciz "tu58 err\r\n"
366end: