Research V1 release
[unix-history] / u8.s
CommitLineData
45cc16b2
KT
1/ u8 -- unix
2
3rtap: / read from the dec tape
4 asr r1 / divide the i-number by 2
5 sub $4.,r1 / (i-number/2)-4 r1
6 mov r1,cdev / cdev now has device number
7 jsr r0,bread; 578. / read in block thats in *u.fofp
8
9wtap:
10 asr r1 / divide i-number by 2
11 sub $4.,r1 / r1 = i-number minus 4
12 mov r1,cdev / this is used as the device number
13 jsr r0,bwrite; 578. / write block (u.fofp) on dec tape
14 / Maximum
15
16rrk0:
17 mov $1,cdev / set current device to i., disk
18 jsr r0,bread; 4872. / read block from disk (maximum block
19 / number allowed on device is 4872.)
20 / - (u.fofp) contains block number
21
22wrk0:
23 mov $1,cdev / set current device to 1; disk
24 jsr r0,bwrite; 4872. / write block (u.fofp) on disk
25
26rrf0:
27 clr cdev / set current device to 0., fixed head disk
28 jsr r0,bread; 1024. / read block (u.fofp) from fixed head
29 / disk (max. block number allowed on
30 / device is 1024.)
31
32wrf0:
33 clr cdev / set current device to 0., fixed head disk
34 jsr r0,bwrite; 1024. / write block '(u.fofp)' on fixed head
35 / disk
36
37bread: / read a block from a block structured device
38 jsr r0,tstdeve / error on special file I/O (only works on
39 / tape)
40 mov *u.fofp,r1 / move block number to r1
41 mov $2.-cold,-(sp) / "2-cold" to stack
421:
43 cmp r1,(r0) / is this block # greater than or equal to
44 / maximum block # allowed on device
45 bhis 1f / yes, 1f (error)
46 mov r1,-(sp) / no, put block # on stack
47 jsr r0,preread / read in the block into an I/O buffer
48 mov (sp)+,r1 / return block # to r1
49 inc r1 / bump block # to next consecutive block
50 dec (sp) / "2-1-cold" on stack
51 bgt 1b / 2-1-cold = 0? No, go back and read in next block
521:
53 tst (sp)+ / yes, pop stack to clear off cold calculation
54 mov *u.fofp,r1 / restore r1 to initial value of the
55 / block #
56 cmp r1,(r0)+ / block # greater than or equal to maximum
57 / block number allowed
58 bhis error10 / yes, error
59 inc *u.fofp / no, *u.fofp has next block number
60 jsr r0,preread / read in the block whose number is in r1
61 bis $40000,(r5) / set bit 14 of the 1st word of the I/O
62 / buffer
631:
64 bit $22000,(r5) / are 10th and 13th bits set (read bits)
65 beq 1f / no
66 cmp cdev,$1 / disk or drum?
67 ble 2f / yes
68 tstb uquant / is the time quantum = 0?
69 bne 2f / no, 2f
70 mov r5,-(sp) / yes, save r5 (buffer address)
71 jsr r0,sleep; 31. / put process to sleep in channel 31 (tape)
72 mov (sp)+,r5 / restore r5
73 br 1b / go back
742: / drum or disk
75 jsr r0,idle; s.wait+2 / wait
76 br 1b
771: / 10th and 13th bits not set
78 bic $40000,(r5) / clear bit 14
79 jsr r0,tstdeve / test device for error (tape)
80 add $8,r5 / r5 points to data in I/O buffer
81 jsr r0,dioreg / do bookkeeping on u.count etc.
821: / r5 points to beginning of data in I/O buffer, r2 points to beginning
83 / of users data
84 movb (r5)+,(r2)+ / move data from the I/O buffer
85 dec r3 / to the user's area in core starting at u.base
86 bne 1b
87 tst u.count / done
88 beq 1f / yes, return
89 tst -(r0) / no, point r0 to the argument again
90 br bread / read some more
911:
92 mov (sp)+,r0 / jump to routine that called readi
93 jmp ret
94
95bwrite: / write on block structured device
96 jsr r0,tstdeve / test the device for an error
97 mov *u.fofp,r1 / put the block number in r1
98 cmp r1,(r0)+ / does block number exceed maximum allowable #
99 bhis error10 / yes, error
100 inc *u.fofp / no, increment block number
101 jsr r0,wslot / get an I/O buffer to write into
102 jsr r0,dioreg / do the necessary bookkeeping
1031: / r2 points to the users data; r5 points to the I/O buffers data area
104 movb (r2)+,(r5)+ / ; r3, has the byte count
105 dec r3 / area to the I/O buffer
106 bne 1b
107 jsr r0,dskwr / write it out on the device
108 tst u.count / done
109 beq 1f / yes, 1f
110 tst -(r0) / no, point r0 to the argument of the call
111 br bwrite / go back and write next block
1121:
113 mov (sp)+,r0 / return to routine that called writei
114 jmp ret
115tstdeve: / check whether permanent error has occured on special file
116 / I/O
117 mov cdev,r1 / only works on tape; r1 has device #
118 tstb deverr(r1) / test error bit of device
119 bne 1f / error
120 rts r0 / device okay
1211:
122 clrb deverr(r1) / clear error
123
124error10:
125 jmp error / see 'error' routine
126
127dioreg:
128 mov u.count,r3 / move char count to r3
129 cmp r3,$512. / more than 512. char?
130 blos 1f / no, branch
131 mov $512.,r3 / yes, just take 512.
1321:
133 mov u.base,r2 / put users base in r2
134 add r3,u.nread / add the number to be read to u.nread
135 sub r3,u.count / update count
136 add r3,u.base / update base
137 rts r0 / return
138
139preread:
140 jsr r0,bufaloc / get a free I/O buffer (r1 has block number)
141 br 1f / branch if block already in a I/O buffer
142 bis $2000,(r5) / set read bit (bit 100 in I/O buffer)
143 jsr r0,poke / perform the read
1441:
145 clr *$ps / ps = 0
146 rts r0
147
148dskrd:
149 jsr r0,bufaloc / shuffle off to bufaloc; get a free I/O buffer
150 br 1f
151 bis $2000,(r5) / set bit 10 of word 1 of I/O queue entry
152 / for buffer
153 jsr r0,poke / just assigned in bufaloc, bit 10=1 says read
1541:
155 clr *$ps
156 bit $22000,(r5) / if either bits 10, or 13 are 1; jump to idle
157 beq 1f
158 jsr r0,idle; s.wait+2
159 br 1b
1601:
161 add $8,r5 / r5 points to first word of data in block just read
162 / in
163 rts r0
164
165wslot:
166 jsr r0,bufaloc / get a free I/O buffer; pointer to first
167 br 1f / word in buffer in r5
1681:
169 bit $22000,(r5) / check bits 10, 13 (read, waiting to read)
170 / of I/O queue entry
171 beq 1f / branch if 10, 13 zero (i.e., not reading, or waiting
172 / to read)
173 jsr r0,idle; s.wait+2 / if buffer is reading or writing to read,
174 / idle
175 br 1b / till finished
1761:
177 bis $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
178 / (write, inhibit bits)
179 clr *$ps / clear processor status
180 add $8,r5 / r5 points to first word in data area for this
181 / block
182 rts r0
183
184dskwr:
185 bic $100000,*bufp / clear bit 15 of I/O queue entry at
186 / bottom of queue
187
188ppoke:
189 mov $340,*$ps
190 jsr r0,poke
191 clr *$ps
192 rts r0
193poke:
194 mov r1,-(sp)
195 mov r2,-(sp)
196 mov r3,-(sp)
197 mov $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority I/O
198 / queue pointer
1991:
200 mov -(r2),r1 / r1 points to an I/O queue entry
201 bit $3000,(r1) / test bits 9 and 10 of word 1 of I/O queue
202 / entry
203 beq 2f / branch to 2f if both are clear
204 bit $130000,(r1) / test bits 12, 13, and 15
205 bne 2f / branch if any are set
206 movb (r1),r3 / get device id
207 tstb deverr(r3) / test for errors on this device
208 beq 3f / branch if no errors
209 mov $-1,2(r1) / destroy associativity
210 clrb 1(r1) / do not do I/O
211 br 2f
2123:
213 cmpb r3,$1 / device id = 1; device is disk
214 blt prf / device id = 0; device is drum
215 bgt ptc / device id greater than or equal to 1; device is
216 / dec tape
217 bit $2,active / test disk busy bit
218 bne 2f / branch if bit is set
219 bis $2,active / set disk busy bit
220 mov r1,rkap / rkap points to current I/O queue entry for disk
221 mov 2(r1),mq / put physical block number in mq
222 mov $12.,div / divide physical block number by 12.
223 mov $rkda+2,r3 /
224 mov ac,-(sp) / put remainder from divide on stack; gives
225 / sector number
226 mov $4,lsh / shift quotient 4 bits, to align with cyl and surf
227 / bits in rkda
228 bis mq,(sp) / or mq with sector; gives total disk address
229 br 3f
230prf: / drum
231 bit $1,active / test drum busy bit
232 bne 2f / branch if bit is set
233 bis $1,active / set drum busy bit
234 mov r1,rfap / rfap points to current I/O queue entry for drum
235 mov $dae+2,r3
236 clr -(sp)
237 movb 2(r1),1(sp) / move low byte of physical block number into
238 / high byte of stack
239 clr -(sp) / word
240 movb 3(r1),(sp) / move high byte of physical block number into
241 / low byte of stack
242 mov (sp)+,-(r3) / load dae with high byte of physical block
243 / number
2443:
245 mov (sp)+,-(r3) / load rkda register; load dar register
246 mov 6(r1),-(r3) / load bus address register
247 mov 4(r1),-(r3) / load word count register
248 mov $103,-(sp) / 103 indicates write operation when loaded
249 / in csr
250 bit $2000,(r1) / if bit 10 of word 1 of I/O queue entry is
251 / a one
252 beq 3f / then read operation is indicated
253 mov $105,(sp) / 105 indicates read operation
2543:
255 mov (sp)+,-(r3) / load csr with interrupt enabled, command, go
256 br seta
257ptc: / tape I/O
258 bit $4,active
259 bne 2f
260 mov tccm,r3
261 swab r3
262 bic $!7,r3
263 add $2,r3
264 cmpb r3,(r1)
265 beq 3f
266 movb $1,tccm / stop transport if not same unit
2673:
268 bis $4,active
269 mov r1,tcap
270 mov $20.,tcerrc
271 mov $tape1,tcstate
272 movb (r1),r3 / device
273 sub $2,r3 / now unit
274 swab r3
275 bis $103,r3 / now rbn,for,unit,ie
276 mov r3,tccm
277 seta: / I/O queue bookkeeping; set read/write waiting bits.
278 mov (r1),r3 / move word 1 of I/O queue entry into r3
279 bic $!3000,r3 / clear all bits except 9 and 10
280 bic $3000,(r1) / clear only bits 9 and 10
281 rol r3
282 rol r3
283 rol r3
284 bis r3,(r1) / or old value of bits 9 and 10 with bits 12
285 / and 13
2862:
287 cmp r2,$bufp / test to see if entire I/O queue has been
288 / scanned
289 bhi 1b
290 mov (sp)+,r3
291 mov (sp)+,r2
292 mov (sp)+,r1
293 rts r0
294
295bufaloc:
296 mov r2,-(sp) / save r2 on stack
297 mov $340,*$ps / set processor priority to 7
2981:
299 clr -(sp) / vacant buffer
300 mov $bufp,r2 / bufp contains pointers to I/O queue entrys
301 / in buffer area
3022:
303 mov (r2)+,r5 / move pointer to word 1 of an I/O queue entry
304 / into r5
305 bit $173000,(r5) / lock+keep+active+outstanding
306 bne 3f / branch when any of bits 9,10,12,13,14,15 are set
307 / (i.e., buffer busy)
308 mov r2,(sp) / save pointer to last non-busy buffer found
309 / points to word 2 of I/O queue entry)
3103:
311 cmpb (r5),cdev / is device in I/O queue entry same as current
312 / device
313 bne 3f
314 cmp 2(r5),r1 / is block number in I/O queue entry, same as
315 / current block number
316 bne 3f
317 tst (sp)+ / bump stack pointer
318 br 1f / use this buffer
3193:
320 cmp r2,$bufp+nbuf+nbuf
321 blo 2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
322 / buffers not checked)
323 mov (sp)+,r2 / once all bufs are examined move pointer to
324 / last free block
325 bne 2f / if (sp) is non zero, i.e., if a free buffer is
326 / found branch to 2f
327 jsr r0,idle; s.wait+2 / idle if no free buffers
328 br 1b
3292:
330 tst (r0)+ / skip if warmed over buffer
3311:
332 mov -(r2),r5 / put pointer to word 1 of I/O queue entry in r5
333 movb cdev,(r5) / put current device number in I/O queue entry
334 mov r1,2(r5) / move block number into word 2 of I/O queue
335/ entry
3361:
337 cmp r2,$bufp / bump all entrys in bufp and put latest assigned
338 blos 1f / buffer on the top (this makes if the lowest priority)
339 mov -(r2),2(r2) / job for a particular device
340 br 1b
3411:
342 mov r5,(r2)
343 mov (sp)+,r2 / restore r2
344 rts r0
345
346tape: / dec tape interrupt
347 jsr r0,setisp / save registers and clockp on stack
348 mov tcstate,r3 / put state of dec tape in r3
349 jsr r0,trapt; tccm; tcap; 4 / busy bit
350 mov r3,pc / device control status register
351 / if no errors, go to device state (an address)
352
353taper: / dec tape error
354 dec tcerrc / decrement the number of errors
355 bne 1f / if more than 1 branch
356 movb 1(r2),r3 / r2+1 points to command register upper byte
357 bic $!7,r3 / clear all but bits 8-10 (Unit Selection)
358 incb deverr+2(r3) / set error bit for this tape unit
359 br tape3
3601: / more than 1 error
361 bit $4000,(r2) / direction of tape
362 beq 1f / if forward go to 1f
363 bic $4000,(r2) / reverse, set to forward
364 mov $tape1,tcstate / put tape 1 in the state
365 br 0f
3661: / put tape in reverse
367 bis $4000,(r2) / set tape to reverse direction
368 mov $tape2,tcstate / put tape 2 as the state
3690:
370 bis $4,active / check active bit of tape
371 movb $103,(r2) / set read function and interrupt enable
372 br 4f / go to retisp
373tape1: / read bn forward
374 mov $tcdt,r0 / move address of data register to r0
375 cmp (r0),2(r1) / compare block addresses
376 blt 0b / if lt, keep moving
377 bgt taper / if gt, reverse
378 mov 6(r1),-(r0) / put bus address in tcba
379 mov 4(r1),-(r0) / put word count in tcwc
380 mov $115,-(sp) / put end interrupt enable
381 bit $20000,(r1) / is "waiting to read bit" of I/O queue set?
382 beq 1f / no, 1f
383 mov $105,(sp) / yes, put and interrupt enable
3841:
385 movb (sp)+,(r2) / move function into command register (tccm)
386 bis $4,active / set active bit
387 mov $tape3,tcstate / get ready for I/O transfer
388 br 4f / go to retisp (rti)
389
390tape2: / read bn bakasswards
391 mov tcdt,r0 / r0 has contents of data register
392 add $3,r0 / overshoot
393 cmp r0,2(r1)
394 bgt 0b / if gt keep reading
395 br taper / else reverse
396
397tape3: / I/O transfer
398 bic $30000,(r1) / clear bits 12 and 13 of I/O queue entry
399 jsr r0,poke / do the I/O
400 bit $4,active / still busy see if pick up r-ahead, w-behind
401 bne 1f / yes
402 movb $1,(r2) / no, indicate too bad
4031:
404 jsr r0,wakeup; runq; 31. / wait up
405 br 4f / retisp
406
407drum: / interrupt handler
408 jsr r0,setisp / save r1,r2,r3, and clockp on the stack
409 jsr r0,trapt; dcs; rfap; 1 / check for stray interrupt or
410 / error
411 br 3f / no, error
412 br 2f / error
413
414disk:
415 jsr r0,setisp / save r1,r2,r3, and clockp on the stack
416 jmp *$0f
4170:
418 jsr r0,trapt; rkcs; rkap; 2
419 br 3f / no, errors
420 mov $115,(r2) / drive reset, errbit was set
421 mov $1f,0b-2 / next time jmp *$0f is executed jmp will be
422 / to 1f
423 br 4f
4241:
425 bit $20000,rkcs
426 beq 4f / wait for seek complete
427 mov $0b,0b-2
428 mov rkap,r1
4292:
430 bit $3000,(r1) / are bits 9 or 10 set in the 1st word of
431 / the disk buffer
432 bne 3f / no, branch ignore error if outstanding
433 inc r1
434 asr (r1)
435 asr (r1)
436 asr (r1) / reissue request
437 dec r1
4383:
439 bic $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
440 mov ac,-(sp)
441 mov mq,-(sp) / put these on the stack
442 mov sc,-(sp)
443 jsr r0,poke
444 mov (sp)+,sc
445 mov (sp)+,mq / pop them off stack
446 mov (sp)+,ac
4474:
448 jmp retisp / u4-3
449
450trapt: / r2 points to the
451 mov (r0)+,r2 / device control register
452 mov *(r0)+,r1 / transaction pointer points to buffer
453 tst (sp)+
454 tstb (r2) / is ready bit of dcs set?
455 bge 4b / device still active so branch
456 bit (r0),active / was device busy?
457 beq 4b / no, stray interrupt
458 bic (r0)+,active / yes, set active to zero
459 tst (r2) / test the err(bit is) of dcs
460 bge 2f / if no error jump to 2f
461 tst (r0)+ / skip on error
462 2:
463 jmp (r0)