Commit | Line | Data |
---|---|---|
cd124064 BJ |
1 | # |
2 | # RP06/RM03 disk boot program to load "/boot" from | |
3 | # a UNIX filesystem (starting at block 1 on pack on | |
4 | # drive 0) into low core and to execute that file. | |
5 | # This program can only read regular small version 7 files | |
6 | # from the root of a UNIX filesystem. | |
7 | # | |
8 | # | |
9 | .set BLKSIZ,1024 # disc block size | |
10 | .set RELOC,0x50000 | |
11 | .set HDRSIZ,040 | |
12 | .set INOSIZ,64 # no. bytes/inode entry | |
13 | .set INOBLK,BLKSIZ/INOSIZ # no. inodes/disc block | |
14 | .set INOMSK,0xfffffff0 # changes with inode size | |
15 | .set NAMSIZ,14 # no. bytes in name field of dir entry | |
16 | .set ENTADR,024 # offset to entry addr in task header | |
17 | .set DIRSIZ,16 # size of directory entry, bytes | |
18 | .set ROOTINO,2 # root dir inode no. | |
19 | .set NBOO,1 | |
20 | .set NSUP,1 | |
21 | .set SLASH,057 # '/' | |
22 | # MBA registers | |
23 | .set MBA0,0x20010000 # MBA 0 device reg's | |
24 | .set M_cr,MBA0+4 # MBA control reg | |
25 | .set M_var,MBA0+12 # MBA virt addr reg | |
26 | .set M_bc,MBA0+16 # MBA byte count reg | |
27 | .set M_map,MBA0+0x800 # start of MBA map reg's | |
28 | .set MBAinit,1 # MBA init bit in MBA control reg | |
29 | # | |
30 | .set RM3SEC,32 | |
31 | .set RM3TRK,5 | |
32 | .set RP6typ,022 | |
33 | .set RM3typ,024 | |
34 | # | |
35 | .set RP6TRK,19 | |
36 | .set RP6SEC,22 | |
37 | .set RP,MBA0+0x400 # start of RP06 drive 0 reg's | |
38 | .set RP_cr,RP+0 # RP06 control reg, drive 0 | |
39 | .set RP_sr,RP+4 # status reg | |
40 | .set RP_stk,RP+0x14 # desired track/sector reg | |
41 | .set RP_dt,RP+0x18 # drive type reg | |
42 | .set RP_off,RP+0x24 # RP offset reg | |
43 | .set RP_cyl,RP+0x28 # desired cyl reg | |
44 | # RP06 function codes, status bits | |
45 | .set RP_GO,1 # GO bit | |
46 | .set RP_RED,070 # read data | |
47 | .set RP_DC,010 # drive clear function code | |
48 | .set RP_RIP,020 # Read-In Preset function code | |
49 | .set RP_FMT,0x1000 # format bit for offset reg | |
50 | .set RP_MOL,0x1000 # medium online in status reg | |
51 | .set RP_DRY,0200 # drive ready, staus reg | |
52 | .set RP_ERR,040000 # composite error, staus reg | |
53 | .set RP_pDRY,7 # bit position of RP_DRY | |
54 | .set RP_pERR,14 # bit position of RP_ERR | |
55 | # | |
56 | # | |
57 | init : | |
58 | # system initialization - executed once per boot load | |
59 | halt # entry mask required by DEC monitor software | |
60 | halt | |
61 | movl $MBAinit,*$M_cr # MBA initialize | |
62 | movl $RP_RIP+RP_GO,*$RP_cr # read-in preset | |
63 | movl $RP_FMT,*$RP_off # format bit in RP offset reg | |
64 | # | |
65 | movl *$RP_dt,r0 | |
66 | cmpb $RP6typ,r0 | |
67 | bneq rm3 | |
68 | movl $RP6SEC,*$rpsec | |
69 | movl $RP6TRK,*$rptrk | |
70 | brb domul | |
71 | rm3: | |
72 | movl $RM3SEC,*$rpsec | |
73 | movl $RM3TRK,*$rptrk | |
74 | domul: | |
75 | mull3 *$rpsec,*$rptrk,*$rpst | |
76 | # move boot image up to higher core | |
77 | start : | |
78 | movl $RELOC,sp | |
79 | # 'uboot' must have no header | |
80 | movc3 $end,*$0,(sp) # move boot to relocated position | |
81 | # | |
82 | # jump to re-located code at 'start2' - done once per boot load | |
83 | jmp *$RELOC+start2 | |
84 | # | |
85 | # execution starts here only after boot has been re-located | |
86 | start2 : | |
87 | # | |
88 | # search inodes for pathname specified in 'names' | |
89 | # | |
90 | # Must preserve r6 & r7 | |
91 | # 'cmpc[35]' instruction uses reg's 0 - 3 | |
92 | # 'movc[35]' instruction uses reg's 0-5 | |
93 | movl $names+RELOC,r6 # start of input filename | |
94 | movzbl $ROOTINO,r0 # start at root inode for search | |
95 | nxti : | |
96 | clrw *$bno # 'bno' is index into 'iaddr[]' in inode entry | |
97 | bsbw iget # get inode into core | |
98 | tstb (r6) # r6 -> empty pathname component if end of pathname | |
99 | beql getfil | |
100 | get1b : | |
101 | bsbw rmblk # read in 1 of blocks in 'addr[]' in inode entry | |
102 | beql start2 # file not found if zero cc set | |
103 | # | |
104 | movl $buf,r7 # buffer holds directory block | |
105 | nxtent : | |
106 | tstw (r7) # null dir entry (inode # field = 0) | |
107 | beql dirchk | |
108 | cmpc3 $NAMSIZ,(r6),2(r7) # compare 'names' against | |
109 | # dir entry - both null-filled | |
110 | bneq dirchk # branch if dir entry is not the one | |
111 | # found component in a dir entry | |
112 | movzwl (r7),r0 # 2-byte inode no. from 1st 2 bytes of dir entry | |
113 | addl2 $NAMSIZ,r6 # point to next pathname component in 'names[]' | |
114 | brb nxti # now go get inode whose no. is in r0 | |
115 | # | |
116 | dirchk : # no pathname match | |
117 | acbl $buf+BLKSIZ-1,$DIRSIZ,r7,nxtent # loop if | |
118 | # more dir entries in this buffer | |
119 | brb get1b # get another dir block into buffer | |
120 | # | |
121 | # here if inode for desired file has been read in | |
122 | getfil : | |
123 | clrl bufptr # new buffer ptr is low core | |
124 | getlop : | |
125 | bsbb rmblk # get a block in the file | |
126 | beql clear # branch if no more file blocks to read | |
127 | # skip above branch if more file blocks to read in | |
128 | addl2 $BLKSIZ,bufptr # next page in low core | |
129 | brb getlop # go get next block of input file | |
130 | # | |
131 | # clear core | |
132 | # | |
133 | clear : | |
134 | movl *$size,r3 | |
135 | clrcor : | |
136 | clrq (r3) | |
137 | acbl $RELOC,$8,r3,clrcor | |
138 | # | |
139 | # go execute file | |
140 | # | |
141 | calls $0,*$0 | |
142 | brw start2 | |
143 | # | |
144 | # | |
145 | # subroutine to get the inode whose no. is in r0 | |
146 | # | |
147 | iget : | |
148 | addl3 $(INOBLK*(NBOO+NSUP))-1,r0,r8 # have to add in 2 blocks (boot and super) | |
149 | # worth of dummy inodes to calculate proper inode block | |
150 | divl3 $INOBLK,r8,r4 # calculate inode block , put in r4 | |
151 | bsbw rblk # read in block containing desired inode | |
152 | bicl2 $INOMSK,r8 | |
153 | mull2 $INOSIZ,r8 # x inode size = offset in block | |
154 | addl2 $buf,r8 # buffer loc of inode entry | |
155 | # move inode entry to separate buffer | |
156 | movc3 $time-inode,(r8),*$inode | |
157 | rsb | |
158 | # | |
159 | # subr to read in 1 of blocks (bno) in 'addr[]' | |
160 | # | |
161 | rmblk : | |
162 | movzwl *$bno,r0 | |
163 | addw2 $3,*$bno # index into 'addr[]' array in inode entry | |
164 | addl2 $addr,r0 | |
165 | # this boot assumes only small files(<11 blocks) | |
166 | extzv $0,$24,(r0),r4 # get low 2 bytes of block no. -> r4 | |
167 | bneq rblk # read in block if non-zero | |
168 | # zero cc is set on return | |
169 | rsb | |
170 | # | |
171 | # subr to read disc block no. specified in r4 from RP06, drive 0 | |
172 | # | |
173 | rblk : | |
174 | mull2 $BLKSIZ/512,r4 | |
175 | clrl r5 | |
176 | ediv *$rpst,r4,*$RP_cyl,r1 | |
177 | # (r4 = block no.)/(no. blocks per cyl) -> cyl no. | |
178 | # r1 = remainder = block offset with in cylinder | |
179 | clrl r2 | |
180 | ediv *$rpsec,r1,r1,r0 | |
181 | # r1 = track no. ; ; sector no. in low part RP_stk | |
182 | insv r1,$8,$5,r0 # move track no. into RP_stk | |
183 | movl r0,*$RP_stk # track-sector | |
184 | movl $-BLKSIZ,*$M_bc # byte count | |
185 | ashl $-9,bufptr,r0 # start page no. of buffer | |
186 | bisl3 $0x80000000,r0,*$M_map # MBA map reg = | |
187 | # valid bit + phys page no. | |
188 | incl r0 | |
189 | bisl3 $0x80000000,r0,*$(M_map+4) | |
190 | clrl *$M_var # buffer has been 512-byte aligned + map reg 0 | |
191 | movl $RP_RED+RP_GO,*$RP_cr # disc read function code | |
192 | rprdy : | |
193 | movl *$RP_sr,r0 | |
194 | bbc $RP_pDRY,r0,rprdy # loop unitl ready | |
195 | bbs $RP_pERR,r0,rperr # branch if error | |
196 | bicpsw $2 # set zero cc for caller success | |
197 | rsb # normal return | |
198 | rperr : # disc i/o error | |
199 | halt # halt on error | |
200 | # | |
201 | # | |
202 | bufptr : .long buf | |
203 | names : | |
204 | .byte 'b,'o,'o,'t,0,0,0,0,0,0,0,0,0,0 | |
205 | .byte 0 | |
206 | # | |
207 | end: | |
208 | # | |
209 | .set buf,RELOC-1536 | |
210 | .set inode,RELOC-512 | |
211 | .set mode,inode | |
212 | .set nlink,mode+2 | |
213 | .set uid,nlink+2 | |
214 | .set gid,uid+2 | |
215 | .set size,gid+2 | |
216 | .set addr,size+4 | |
217 | .set time,addr+40 | |
218 | .set bno,time+12 | |
219 | .set rptrk,bno+4 | |
220 | .set rpsec,rptrk+4 | |
221 | .set rpst,rpsec+4 |