Commit | Line | Data |
---|---|---|
45cc16b2 KT |
1 | / u8 -- unix |
2 | ||
3 | rtap: / 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 | ||
9 | wtap: | |
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 | ||
16 | rrk0: | |
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 | ||
22 | wrk0: | |
23 | mov $1,cdev / set current device to 1; disk | |
24 | jsr r0,bwrite; 4872. / write block (u.fofp) on disk | |
25 | ||
26 | rrf0: | |
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 | ||
32 | wrf0: | |
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 | ||
37 | bread: / 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 | |
42 | 1: | |
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 | |
52 | 1: | |
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 | |
63 | 1: | |
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 | |
74 | 2: / drum or disk | |
75 | jsr r0,idle; s.wait+2 / wait | |
76 | br 1b | |
77 | 1: / 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. | |
82 | 1: / 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 | |
91 | 1: | |
92 | mov (sp)+,r0 / jump to routine that called readi | |
93 | jmp ret | |
94 | ||
95 | bwrite: / 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 | |
103 | 1: / 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 | |
112 | 1: | |
113 | mov (sp)+,r0 / return to routine that called writei | |
114 | jmp ret | |
115 | tstdeve: / 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 | |
121 | 1: | |
122 | clrb deverr(r1) / clear error | |
123 | ||
124 | error10: | |
125 | jmp error / see 'error' routine | |
126 | ||
127 | dioreg: | |
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. | |
132 | 1: | |
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 | ||
139 | preread: | |
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 | |
144 | 1: | |
145 | clr *$ps / ps = 0 | |
146 | rts r0 | |
147 | ||
148 | dskrd: | |
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 | |
154 | 1: | |
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 | |
160 | 1: | |
161 | add $8,r5 / r5 points to first word of data in block just read | |
162 | / in | |
163 | rts r0 | |
164 | ||
165 | wslot: | |
166 | jsr r0,bufaloc / get a free I/O buffer; pointer to first | |
167 | br 1f / word in buffer in r5 | |
168 | 1: | |
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 | |
176 | 1: | |
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 | ||
184 | dskwr: | |
185 | bic $100000,*bufp / clear bit 15 of I/O queue entry at | |
186 | / bottom of queue | |
187 | ||
188 | ppoke: | |
189 | mov $340,*$ps | |
190 | jsr r0,poke | |
191 | clr *$ps | |
192 | rts r0 | |
193 | poke: | |
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 | |
199 | 1: | |
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 | |
212 | 3: | |
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 | |
230 | prf: / 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 | |
244 | 3: | |
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 | |
254 | 3: | |
255 | mov (sp)+,-(r3) / load csr with interrupt enabled, command, go | |
256 | br seta | |
257 | ptc: / 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 | |
267 | 3: | |
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 | |
286 | 2: | |
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 | ||
295 | bufaloc: | |
296 | mov r2,-(sp) / save r2 on stack | |
297 | mov $340,*$ps / set processor priority to 7 | |
298 | 1: | |
299 | clr -(sp) / vacant buffer | |
300 | mov $bufp,r2 / bufp contains pointers to I/O queue entrys | |
301 | / in buffer area | |
302 | 2: | |
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) | |
310 | 3: | |
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 | |
319 | 3: | |
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 | |
329 | 2: | |
330 | tst (r0)+ / skip if warmed over buffer | |
331 | 1: | |
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 | |
336 | 1: | |
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 | |
341 | 1: | |
342 | mov r5,(r2) | |
343 | mov (sp)+,r2 / restore r2 | |
344 | rts r0 | |
345 | ||
346 | tape: / 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 | ||
353 | taper: / 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 | |
360 | 1: / 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 | |
366 | 1: / put tape in reverse | |
367 | bis $4000,(r2) / set tape to reverse direction | |
368 | mov $tape2,tcstate / put tape 2 as the state | |
369 | 0: | |
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 | |
373 | tape1: / 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 | |
384 | 1: | |
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 | ||
390 | tape2: / 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 | ||
397 | tape3: / 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 | |
403 | 1: | |
404 | jsr r0,wakeup; runq; 31. / wait up | |
405 | br 4f / retisp | |
406 | ||
407 | drum: / 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 | ||
414 | disk: | |
415 | jsr r0,setisp / save r1,r2,r3, and clockp on the stack | |
416 | jmp *$0f | |
417 | 0: | |
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 | |
424 | 1: | |
425 | bit $20000,rkcs | |
426 | beq 4f / wait for seek complete | |
427 | mov $0b,0b-2 | |
428 | mov rkap,r1 | |
429 | 2: | |
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 | |
438 | 3: | |
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 | |
447 | 4: | |
448 | jmp retisp / u4-3 | |
449 | ||
450 | trapt: / 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) |