1 /* utboot.c 6.1 83/07/29 */ 2 3 /* 4 * VAX tape boot block for distribution tapes 5 * works on unibus tm03 6 * 7 * reads a program from a tp directory on a tape and executes it 8 * program must be stripped of the header and is loaded ``bits as is'' 9 * you can return to this loader via ``ret'' as you are called ``calls $0,ent'' 10 */ 11 .set RELOC,0x70000 12 /* a.out defines */ 13 .set HDRSIZ,040 /* size of file header for VAX */ 14 .set MAGIC,0410 /* file type id in header */ 15 .set TSIZ,4 /* text size */ 16 .set DSIZ,8 /* data size */ 17 .set BSIZ,12 /* bss size */ 18 .set TENT,024 /* task header entry loc */ 19 /* tp directory definitions */ 20 .set FILSIZ,38 /* tp direc offset for file size */ 21 .set BNUM,44 /* tp dir offset for start block no. */ 22 .set ENTSIZ,64 /* size of 1 TP dir entry, bytes */ 23 .set PTHSIZ,32 /* size of TP path name, bytes */ 24 .set BLKSIZ,512 /* tape block size, bytes */ 25 .set NUMDIR,24 /* no. of dir blocks on tape */ 26 .set ENTBLK,8 /* no. of dir entries per tape block */ 27 /* processor registers and bits */ 28 .set RXCS,32 29 .set RXDB,33 30 .set TXCS,34 31 .set TXDB,35 32 .set RXCS_DONE,0x80 33 .set TXCS_RDY,0x80 34 .set TXCS_pr,7 /* bit position of TXCS ready bit */ 35 .set RXCS_pd,7 /* bit position of RXCS done bit */ 36 /* UBA registers */ 37 .set UBA_DPR1,68 38 .set UBA_MAP,2048 39 .set BNE,0x80000000 40 .set MRV,0x80000000 41 .set MR_BDP1,0x200000 42 43 /* UT UBA registers */ 44 .set UTCS1,0 45 .set UTWC,02 46 .set UTBA,04 47 .set UTFC,06 48 .set UTCS2,010 49 .set UTDS,012 50 .set UTER,014 51 .set UTAS,016 52 .set UTCC,020 53 .set UTDB,022 54 .set UTMR,024 55 .set UTDT,026 56 .set UTSN,030 57 .set UTTC,032 58 59 /* UT commands and bits */ 60 .set GO,01 61 .set UT_REW,0x6 62 .set UT_RCOM,0x38 63 .set UT_SREV,0x1a 64 .set UT_DCLR,0x8 65 .set UT_crdy,0x80 66 .set UT_gapsd,0x2000 /* aka "positioning in progress" */ 67 .set UTDENS,0x4c0 /* 1600 bpi, PDP-11 format */ 68 /* local stack variables */ 69 .set tapa,-4 /* desired tape addr */ 70 .set mtapa,-8 /* current tape addr */ 71 .set name,-8-PTHSIZ /* operator-typed file name */ 72 /* register usage */ 73 .set rUBA,r10 74 .set rUT,r11 75 /* ===== */ 76 77 /* initialization */ 78 init: 79 movl $RELOC,fp /* core loc to which to move this program */ 80 addl3 $name,fp,sp /* set stack pointer; leave room for locals */ 81 clrl r0 82 1: 83 movc3 $end,(r0),(fp) /* move boot up to relocated position */ 84 jmp start+RELOC 85 start: 86 bsbw rew /* rewind input tape */ 87 movab name(fp),r4 /* start of filename storage */ 88 movzbl $'=,r0 /* prompt character */ 89 bsbw putc /* output char to main console */ 90 /* read in a file name */ 91 movl r4,r1 /* loc at which to store file name */ 92 nxtc: 93 bsbw getc /* get input char's in file name */ 94 cmpb r0,$012 /* terminator ? */ 95 beql nullc 96 movb r0,(r1)+ 97 brb nxtc 98 nullc: 99 subl3 r4,r1,r9 /* size of path name */ 100 beql start /* dumb operator */ 101 clrb (r1)+ 102 incl r9 103 /* user-specified TP filename has been stored at name(fp) */ 104 /* read in entire tp directory contents into low core */ 105 dirred: 106 movl $8,tapa(fp) /* tp directory starts at block 8 */ 107 movl $(NUMDIR*BLKSIZ),r6 /* no. bytes in total dir */ 108 bsbw taper /* read no. bytes indicated */ 109 /* search entire directory for user-specified file name */ 110 clrl r5 /* dir buff loc = 0 */ 111 nxtdir: 112 cmpc3 r9,(r5),(r4) /* see if dir entry matches filename */ 113 beql fndfil /* found match */ 114 acbl $NUMDIR*BLKSIZ-1,$ENTSIZ,r5,nxtdir 115 /* see if done with tp dir */ 116 brw start /* entry not in directory; start over */ 117 /* found desired tp dir entry */ 118 fndfil: 119 movzwl BNUM(r5),tapa(fp) /* start block no., 2 bytes */ 120 addl2 $7,tapa(fp) /* skip 7 boot blocks */ 121 movzwl FILSIZ(r5),r6 /* low 2 bytes file size */ 122 insv FILSIZ-1(r5),$16,$8,r6 /* file size, high byte */ 123 cmpl r6,$RELOC-512 /* check if file fits below stack */ 124 blss filok /* file o.k. */ 125 brw start /* file too large */ 126 /* time to read in desired file from tape */ 127 filok: 128 movl r6,r7 /* save r6 */ 129 bsbb taper 130 bsbw rew 131 /* clear core */ 132 subl3 r7,$RELOC-4,r0 /* no. bytes to clear */ 133 1: 134 clrb (r7)+ 135 sobgtr r0,1b 136 /* time to jump to start of file & execute */ 137 addl3 $20,fp,ap 138 clrl r5 139 calls $0,(r5) 140 brw start 141 /* taper: movcTAPE (r6),tapa(fp),0 */ 142 rew2: 143 bsbb rew /* beginning of tape */ 144 taper0: 145 bsbb rrec /* advance 1 block; never want blk 0 */ 146 taper: 147 clrl r0 /* page no. */ 148 cmpl mtapa(fp),tapa(fp) /* current position .vs. desired */ 149 bgtr rew2 150 blss taper0 151 1: 152 bsbb rrec 153 acbl $1,$-BLKSIZ,r6,1b 154 rsb 155 /* rew: rewind the tape */ 156 rew: 157 clrl mtapa(fp) /* current position */ 158 movw $UTDENS,UTTC(%rUT) /* select drive */ 159 movw $UT_REW+GO,UTCS1(%rUT) 160 rsb 161 /* rrec: read 1 block from mag tape into page (r0) */ 162 rrec: 163 /* pushl r0; movzbl $'r,r0; bsbw putc; movl (sp)+,r0; */ 164 jsb utquiet 165 movw $-BLKSIZ,UTFC(%rUT) 166 movw $-256,UTWC(%rUT) /* !!!!!!!!!!!!!! */ 167 bisl3 $MRV|MR_BDP1,r0,UBA_MAP(%rUBA) 168 movw $0,UTBA(%rUT) 169 movw $UTDENS,UTTC(%rUT) /* select drive */ 170 movw $UT_RCOM+GO,UTCS1(%rUT) 171 jsb utquiet 172 bisl2 $BNE,UBA_DPR1(%rUBA) 173 tstw UTER(%rUT) 174 jgeq 2f 175 mnegw $1,UTWC(%rUT) 176 movw $UTDENS,UTTC(%rUT) /* select drive */ 177 movw $UT_SREV+GO,UTCS1(%rUT) 178 jmp rrec 179 2: 180 incl r0 /* next page no. */ 181 incl mtapa(fp) /* mag tape block position */ 182 rsb 183 getc: 184 mfpr $RXCS,r0 185 bbc $RXCS_pd,r0,getc /* receiver ready ? */ 186 mfpr $RXDB,r0 187 extzv $0,$7,r0,r0 188 cmpb r0,$015 189 bneq putc 190 bsbb putc 191 movb $0,r0 192 bsbb putc 193 movb $012,r0 194 putc: 195 mfpr $TXCS,r2 196 bbc $TXCS_pr,r2,putc /* transmitter ready ? */ 197 extzv $0,$7,r0,r0 198 mtpr r0,$TXDB 199 rsb 200 utquiet: 201 movw UTCS1(%rUT),r2 202 bbc $UT_crdy,r2,utquiet 203 1: 204 movw UTDS(%rUT),r2 205 bbs $UT_gapsd,r2,1b 206 rsb 207 end: 208