0
|
1 ********************************************************************
|
1280
|
2 * PipeMan - OS-9 Pipe File Manager
|
0
|
3 *
|
|
4 * $Id$
|
|
5 *
|
1280
|
6 * Some tests under NitrOS-9:
|
|
7 *
|
|
8 * 'show grf.3.a | eat' (eat is cat, but just does a I$ReadLn, and not I$WritLn)
|
|
9 * April 10, 1996 14:05:15
|
|
10 * April 10, 1996 14:07:47
|
|
11 * 15.2 seconds per iteration
|
|
12 * i.e. everything but the screen writes
|
|
13 *
|
|
14 * fast SCF+fast pipe
|
|
15 * 'show grf.3.a | cat', 10 times
|
|
16 * April 10, 1996 13:17:54
|
|
17 * April 10, 1996 13:21:57
|
|
18 * 24.3 seconds per iteration
|
|
19 * 9.1 solely for pipes
|
|
20 *
|
|
21 * fast SCF+old slow pipe
|
|
22 * April 10, 1996 13:30:24
|
|
23 * April 10, 1996 13:38:04
|
|
24 * 46.0 seconds per iteration
|
|
25 * 30.8 solely for pipes
|
|
26 *
|
|
27 * speedup percent is (30.8-9.1)/30.8 = 70%
|
|
28 *
|
|
29 * Pipes are more than doubled in speed!
|
|
30 *
|
|
31 * 32 byte read and write buffers
|
|
32 *
|
|
33 * Edt/Rev YYYY/MM/DD Modified by
|
|
34 * Comment
|
0
|
35 * ------------------------------------------------------------------
|
1280
|
36 * 4 ????/??/?? Alan DeKok
|
|
37 * Enhanced and re-written.
|
|
38 *
|
|
39 * 5r0 2003/08/27 Boisy G. Pitre
|
|
40 * Back-ported from OS-9 Level Two to OS-9 Level One.
|
0
|
41
|
|
42 nam PipeMan
|
1280
|
43 ttl OS-9 Pipe File Manager
|
0
|
44
|
|
45 ifp1
|
|
46 use defsfile
|
1280
|
47 use pipedefs
|
|
48 use scfdefs
|
0
|
49 endc
|
|
50
|
|
51 tylg set FlMgr+Objct
|
1280
|
52 atrv set ReEnt+Rev
|
|
53 rev set $00
|
|
54 edition set 5
|
0
|
55
|
|
56 mod eom,name,tylg,atrv,start,size
|
|
57
|
1280
|
58 rmb $0000
|
0
|
59 size equ .
|
|
60
|
1280
|
61
|
|
62 org $0000
|
|
63 P.CPR rmb 1 process ID
|
|
64 P.CNT rmb 1 count
|
|
65 P.SIG rmb 1 signal code
|
|
66 P.FLAG rmb 1 raw/edit flag
|
|
67
|
0
|
68 name fcs /PipeMan/
|
|
69 fcb edition
|
|
70
|
1279
|
71 start lbra Create
|
|
72 lbra Open
|
|
73 lbra MakDir
|
|
74 lbra ChgDir
|
|
75 lbra Delete
|
1280
|
76 *
|
|
77 * I$Seek Entry Point
|
|
78 *
|
|
79 * Entry:
|
|
80 *
|
|
81 * Exit:
|
|
82 *
|
|
83 * Error: CC Carry set
|
|
84 * B = errcode
|
|
85 *
|
|
86 Seek clrb
|
|
87 rts
|
|
88 nop
|
1279
|
89 lbra Read
|
|
90 lbra Write
|
|
91 lbra ReadLn
|
|
92 lbra WritLn
|
1280
|
93
|
|
94 *
|
|
95 * I$GetStat Entry Point
|
|
96 *
|
|
97 * Entry:
|
|
98 *
|
|
99 * Exit:
|
|
100 *
|
|
101 * Error: CC Carry set
|
|
102 * B = errcode
|
|
103 *
|
|
104 GetStt clrb
|
|
105 rts
|
|
106 nop
|
|
107
|
|
108 *
|
|
109 * I$SetStat Entry Point
|
|
110 *
|
|
111 * Entry:
|
|
112 *
|
|
113 * Exit:
|
|
114 *
|
|
115 * Error: CC Carry set
|
|
116 * B = errcode
|
|
117 *
|
|
118 SetStt clrb
|
|
119 rts
|
|
120 nop
|
|
121
|
|
122 *
|
|
123 * I$Close Entry Point
|
|
124 *
|
|
125 * Entry: A = path number
|
|
126 *
|
|
127 * Exit:
|
|
128 *
|
|
129 * Error: CC Carry set
|
|
130 * B = errcode
|
|
131 *
|
|
132 Close lda PD.CNT,y
|
|
133 bne L008E
|
|
134 ldu PD.BUF,y if no one's using it,
|
|
135 clrb
|
|
136 inca
|
|
137 os9 F$SRtMem return the memory
|
|
138 clrb
|
|
139 rts
|
|
140
|
|
141 L008E leax PD.Read,y
|
|
142 cmpa PD.Read+P.CNT,y is the read count zero?
|
|
143 beq L009C
|
|
144
|
|
145 cmpa PD.Writ+P.CNT,y is the write count zero?
|
|
146 bne L00A9
|
|
147 leax PD.Writ,y
|
|
148
|
|
149 L009C lda P.CPR,x get process ID that's reading/writing
|
|
150 beq L00A9 if none
|
|
151 ldb P.SIG,x get signal code
|
|
152 beq L00A9
|
|
153 clr P.SIG,x
|
|
154 os9 F$Send send a wake-up signal to the process
|
|
155 L00A9 clrb
|
0
|
156 rts
|
1280
|
157
|
|
158 *
|
|
159 * I$MakDir Entry Point
|
|
160 *
|
|
161 * Entry: X = address of the pathlist
|
|
162 *
|
|
163 * Exit: X = last byte of pathlist address
|
|
164 *
|
|
165 * Error: CC Carry set
|
|
166 * B = errcode
|
|
167 *
|
|
168 MakDir equ *
|
|
169
|
|
170 *
|
|
171 * I$ChgDir Entry Point
|
|
172 *
|
|
173 * Entry:
|
|
174 *
|
|
175 * Exit:
|
|
176 *
|
|
177 * Error: CC Carry set
|
|
178 * B = errcode
|
|
179 *
|
|
180 ChgDir equ *
|
|
181
|
|
182 *
|
|
183 * I$Delete Entry Point
|
|
184 *
|
|
185 * Entry:
|
|
186 *
|
|
187 * Exit:
|
|
188 *
|
|
189 * Error: CC Carry set
|
|
190 * B = errcode
|
|
191 *
|
|
192 Delete equ *
|
|
193 comb
|
|
194 ldb #E$UnkSVC
|
|
195 rts
|
|
196
|
|
197 *
|
|
198 * I$Create Entry Point
|
|
199 *
|
|
200 * Entry: A = access mode desired
|
|
201 * B = file attributes
|
|
202 * X = address of the pathlist
|
|
203 *
|
|
204 * Exit: A = pathnum
|
|
205 * X = last byte of pathlist address
|
|
206 *
|
|
207 * Error: CC Carry set
|
|
208 * B = errcode
|
|
209 *
|
|
210 Create equ *
|
|
211
|
|
212 *
|
|
213 * I$Open Entry Point
|
|
214 *
|
|
215 * Entry: A = access mode desired
|
|
216 * X = address of the pathlist
|
|
217 *
|
|
218 * Exit: A = pathnum
|
|
219 * X = last byte of pathlist address
|
|
220 *
|
|
221 * Error: CC Carry set
|
|
222 * B = errcode
|
|
223 *
|
|
224 Open equ *
|
|
225 ldx R$X,u get address of filename to open
|
|
226 pshs y save PD pointer
|
|
227 os9 F$PrsNam parse /pipe
|
|
228 bcs L007B exit on error
|
|
229 IFGT Level-1
|
|
230 ldx <D.Proc current process ptr
|
|
231 ldb P$Task,x get task number for call, below
|
|
232 leax -$01,y back up one character
|
|
233 os9 F$LDABX get last character of the filename
|
|
234 tsta check the character
|
|
235 ELSE
|
|
236 * leax -1,y
|
|
237 lda -1,y
|
|
238 ENDC
|
|
239 bmi L0060 if high bit set, it's OK
|
|
240 leax ,y point to next bit
|
|
241 os9 F$PrsNam else parse name
|
|
242 bcc L007B if no error, it's a sub-dir, and we error out
|
|
243 L0060 sty R$X,u save new pathname ptr
|
|
244 puls y restore PD pointer
|
0
|
245 ldd #$0100
|
1280
|
246 os9 F$SRqMem request one page for the pipe
|
|
247 bcs L007A exit on error
|
|
248 stu PD.BUF,y save ptr to the buffer
|
|
249 stu <PD.NxtI,y save write pointer
|
|
250 stu <PD.NxtO,y and read pointer
|
|
251 leau d,u point to the end of the buffer
|
|
252 stu <PD.End,y save save the ptr
|
|
253 L007A rts
|
|
254
|
|
255 L007B comb
|
|
256 ldb #E$BPNam bad path name
|
0
|
257 puls pc,y
|
1280
|
258
|
|
259 *
|
|
260 * I$ReadLn Entry Point
|
|
261 *
|
|
262 * Entry:
|
|
263 *
|
|
264 * Exit:
|
|
265 *
|
|
266 * Error: CC Carry set
|
|
267 * B = errcode
|
|
268 *
|
1279
|
269 ReadLn ldb #$0D
|
1280
|
270 fcb $21 skip one byte
|
|
271
|
|
272 *
|
|
273 * I$Read Entry Point
|
|
274 *
|
|
275 * Entry:
|
|
276 *
|
|
277 * Exit:
|
|
278 *
|
|
279 * Error: CC Carry set
|
|
280 * B = errcode
|
|
281 *
|
|
282 Read clrb
|
|
283 stb PD.Read+P.FLAG,y raw read
|
|
284 leax PD.Read,y
|
|
285 lbsr L0160 send wakeup signals to process
|
|
286 bcs L0100 on error, wake up writing process
|
|
287 ldx R$Y,u
|
|
288 beq L0100 if no bytes to rwad
|
|
289 ldd R$X,u start address to read from
|
|
290 leax d,x add in number of bytes: end address
|
|
291
|
|
292 * NOTE: PD.RGS,Y will change as the processes read/write the pipe,
|
|
293 * and sleep.
|
|
294 pshs u save current caller's register stack
|
|
295 leas -32,s reserve a 32-byte buffer on the stack
|
|
296 leau ,s point to the start of the buffer
|
|
297 pshs d,x save start, end to read
|
|
298
|
|
299 clrb no bytes read to user yet
|
|
300 puls x restore number of data bytes read, read address
|
|
301 L00DB bsr L01F2 are we blocked?
|
|
302 bcs L00C8 yes, send a signal
|
|
303 sta b,u store the byte in the internal read buffer
|
|
304 leax $01,x go up by one byte
|
|
305 incb one more byte in the buffer
|
|
306 cmpb #32 reached maximum size of the buffer?
|
|
307 blo L00E0 no, continue
|
|
308 bsr read.out read 32 bytes of data to the caller
|
|
309
|
|
310 L00E0 tst PD.Read+P.FLAG,Y was it a raw read?
|
|
311 beq L00ED skip ahead if raw
|
|
312 cmpa #C$CR was the character a CR?
|
|
313 beq L00F1 yes, we're done: flush and exit
|
|
314 L00ED cmpx ,s or at end of data to read?
|
|
315 blo L00DB no, keep reading
|
|
316
|
|
317 L00F1 bsr read.out flush the rest of the pipe buffer to the user
|
|
318 L00F2 tfr x,d this is how far we got
|
|
319 subd ,s++ take out start of buffer
|
|
320 leas 32,s kill our on-stack buffer
|
|
321 puls u restore caller's register stack ptr: NOT PD.RGS,Y
|
|
322 addd R$Y,u add in number of bytes
|
|
323 std R$Y,u save bytes read
|
|
324 bne L00FF if not zero
|
|
325 ldb #E$EOF zero bytes read:EOF error
|
|
326 fcb $21 skip one byte
|
|
327
|
|
328 L00FF clrb no errors
|
|
329 L0100 leax PD.Read,y read data ptr
|
|
330 lbra L01BD signal other it's OK to go ahead
|
|
331
|
|
332 read.out pshs a,x,y,u save registers
|
|
333 tstb any data to write?
|
|
334 beq read.ex no, skip ahead
|
|
335 IFGT Level-1
|
|
336 clra make 16-bit data length
|
|
337 tfr d,y number of data bytes to read to user
|
|
338 negb make it negative
|
|
339 leax b,x back up TO pointer
|
|
340 pshs x save it
|
|
341 leax ,u point to the start of the buffer
|
|
342 ldu <D.Proc current process pointer
|
|
343 ldb P$Task,u A=$00 from above, already
|
|
344 puls u restore TO pointer
|
|
345 os9 F$Move move the data over
|
|
346 clrb no bytes read to the caller yet
|
|
347 ELSE
|
|
348 tfr b,a copy byte count to A
|
|
349 nega make it negative
|
|
350 leax a,x back up TO pointer
|
|
351 ReadLoop lda ,u+
|
0
|
352 sta ,x+
|
1280
|
353 decb
|
|
354 bne ReadLoop
|
|
355 ENDC
|
|
356 read.ex puls a,x,y,u,pc restore registers and exit
|
|
357
|
|
358 L00C8 pshs x save read pointer
|
|
359 bsr read.out dump data out to the user
|
|
360 pshs b save number of bytes read
|
|
361 leax PD.Read,y read data area ptr
|
|
362 lbsr L018B setup for signal
|
|
363 puls x,b restore registers: note B=$00, but we CANNOT do a
|
|
364 bcc L00DB clrb, because this line needs CC.C!
|
|
365 bra L00F2 don't write data out again, but exit
|
|
366
|
|
367 * Check if we're blocked
|
|
368 L01F2 lda <PD.RFlg,y we blocked?
|
|
369 bne L01F9 no, skip ahead
|
|
370 coma set flag: blocked
|
|
371 rts and return to the caller
|
|
372
|
|
373 L01F9 pshs x save read ptr
|
|
374 ldx <PD.NxtO,y where to read from in the buffer
|
|
375 lda ,x+ get a byte
|
|
376 cmpx <PD.End,y at the end of the buffer?
|
|
377 blo L0207 no, skip ahesd
|
|
378 ldx PD.BUF,y yes, go to start
|
|
379 L0207 stx <PD.NxtO,y save new read ptr
|
|
380 cmpx <PD.NxtI,y caught up to the write pointer yet?
|
|
381 bne L0212 no, skeip ahead
|
|
382 clr <PD.RFlg,y yes, set read is blocked
|
|
383 L0212 andcc #^Carry no errors
|
|
384 puls pc,x restore regs and exit
|
|
385
|
|
386 L0160 lda P.CPR,x get current process
|
|
387 beq L0185 none, exit
|
|
388 cmpa PD.CPR,y current process ID
|
|
389 beq L0189 none, exit
|
|
390 inc P.CNT,x one more process using this pipe
|
|
391 ldb P.CNT,x
|
|
392 cmpb PD.CNT,y same as the number for this path?
|
|
393 bne L0173 no, skip ahead
|
|
394 lbsr L009C no, send a wake-up signal
|
|
395 L0173 os9 F$IOQu and insert it in the others IO queue
|
|
396 dec P.CNT,x decrement count
|
|
397 pshs x
|
|
398 ldx <D.Proc current process ptr
|
|
399 ldb <P$Signal,x signal code
|
0
|
400 puls x
|
1280
|
401 beq L0160 if no signal code sent, do another process
|
|
402 coma otherwise return CC.C set, and B=signal code
|
0
|
403 rts
|
1280
|
404
|
|
405 L0185 ldb PD.CPR,y grab current PD process
|
|
406 stb P.CPR,x save as current reading/writing process
|
|
407 L0189 clrb no errors
|
|
408 rts and exit
|
|
409
|
|
410 L01CC pshs b,x save regs
|
|
411 ldx <PD.NxtI,y
|
|
412 ldb <PD.RFlg,y 0=READ, 1=WRITE
|
|
413 beq L01DE was reading, set to write and continue
|
|
414 cmpx <PD.NxtO,y caught up to the read pointer yet?
|
|
415 bne L01E3
|
0
|
416 comb
|
|
417 puls pc,x,b
|
1280
|
418
|
|
419 L01DE inc <PD.RFlg,y set to writing into the pipe
|
|
420 L01E3 sta ,X+ save the byte
|
|
421 cmpx <PD.End,y if at the end of the buffer
|
|
422 blo L01EC
|
|
423 ldx PD.BUF,y reset to the beginning
|
|
424 L01EC stx <PD.NxtI,y
|
0
|
425 clrb
|
|
426 puls pc,x,b
|
1280
|
427
|
|
428 write.in pshs a,x,y save registers
|
|
429 leau -32,u point to the start of the buffer again
|
|
430 IFGT Level-1
|
|
431 ldx <D.Proc current process pointer
|
|
432 lda P$Task,x get FROM task number for this process
|
|
433 ldx 1,s get FROM pointer
|
|
434 ldy #32 16 bytes to grab
|
|
435 clrb TO the system task
|
|
436 os9 F$Move
|
|
437 ELSE
|
|
438 ldb #31
|
|
439 WritLoop lda b,x
|
|
440 sta b,u
|
|
441 decb
|
|
442 bpl WritLoop
|
|
443 ENDC
|
|
444 ldb #32 16 bytes in the buffer
|
|
445 puls a,x,y,pc
|
|
446
|
|
447 *
|
|
448 * I$WritLn Entry Point
|
|
449 *
|
|
450 * Entry:
|
|
451 *
|
|
452 * Exit:
|
|
453 *
|
|
454 * Error: CC Carry set
|
|
455 * B = errcode
|
|
456 *
|
|
457 WritLn ldb #$0D
|
|
458 fcb $21 skip one byte
|
|
459
|
|
460 *
|
|
461 * I$Write Entry Point
|
|
462 *
|
|
463 * Entry:
|
|
464 *
|
|
465 * Exit:
|
|
466 *
|
|
467 * Error: CC Carry set
|
|
468 * B = errcode
|
|
469 *
|
|
470 Write clrb
|
|
471 stb <PD.Writ+P.FLAG,y
|
|
472 leax PD.Writ,y
|
|
473 bsr L0160 make sure it's OK
|
|
474 bcs L015C
|
|
475 ldx R$Y,u get number of bytes to write
|
|
476 beq L015C
|
|
477 ldd R$X,u start address
|
|
478 leax d,x add in number of bytes
|
|
479 pshs u
|
|
480 leau ,s point to the end of the buffer
|
|
481 leas -32,s
|
|
482 pshs d,x save start, end
|
|
483
|
|
484 ldx ,s get initial start pointer
|
|
485 bsr write.in fill the write buffer
|
|
486
|
|
487 puls x
|
|
488 L0137 lda ,u
|
|
489 bsr L01CC save it in the buffer
|
|
490 bcs L0124 caught up to reading process yet?
|
|
491 leax $01,x up by one byte
|
|
492 leau 1,u
|
|
493 decb
|
|
494 bne L0138
|
|
495 bsr write.in fill the buffer again
|
|
496
|
|
497 L0138 tst <PD.Writ+P.FLAG,y
|
|
498 beq L014B
|
|
499 cmpa #C$CR at the end of a line to output?
|
|
500 beq L014F
|
|
501 L014B cmpx ,S at end yet?
|
|
502 blo L0137 if not, read more data
|
|
503 L014F clrb clear carry and error
|
|
504 L0150 ldu 2+32,s skip END, 32-byte write buffer, get U
|
|
505 pshs b,cc
|
|
506 tfr x,d
|
|
507 subd $02,s take out end address
|
|
508 addd R$Y,u add in number of bytes
|
|
509 std R$Y,u save bytes written
|
|
510 puls x,b,cc
|
|
511 leas 32,s kill write buffer
|
|
512 puls u
|
|
513
|
|
514 L015C leax PD.Writ,y
|
|
515 * can probably lose saving 'U' in next few lines... but only minor difference
|
|
516 * Signal read/write it's OK to go ahead
|
|
517 L01BD pshs u,b,cc
|
|
518 clr P.CPR,x NO process currently using this device
|
|
519 bsr Other signal other process to start
|
|
520 puls pc,u,b,cc
|
|
521
|
|
522 L0124 pshs x,b
|
|
523 leax PD.Writ,y
|
|
524 bsr L018B send signal to other
|
|
525 tfr b,a save error code, if applicable
|
|
526 puls x,b restore pointer, byte count
|
|
527 bcc L0137 continue if OK
|
|
528 tfr a,b otherwise restore error code
|
|
529 bra L0150 exit, returning the error code to the user
|
|
530
|
|
531 L018B ldb P.CNT,x
|
|
532 incb
|
|
533 cmpb PD.CNT,y
|
|
534 beq L01B9
|
|
535 stb P.CNT,x
|
|
536 ldb #$01
|
|
537 stb P.SIG,x
|
|
538 clr PD.CPR,y
|
|
539 pshs x
|
|
540 bsr Other
|
|
541 ldx #$0000 make X=0
|
|
542 os9 F$Sleep sleep forever
|
|
543 ldx <D.Proc
|
|
544 ldb <P$Signal,x get signal code
|
|
545 puls x
|
|
546 dec P.CNT,x
|
|
547 tstb
|
|
548 bne L01BB if a signal, we can't wake up
|
|
549 clrb the writing process
|
0
|
550 rts
|
1280
|
551
|
|
552 L01B9 ldb #E$Write write error
|
|
553 L01BB coma
|
|
554 rts
|
|
555
|
|
556 Other exg x,d
|
|
557 eorb #$04 if r/w go to w/r
|
|
558 exg d,x
|
|
559 lbra L009C
|
0
|
560
|
|
561 emod
|
|
562 eom equ *
|
|
563 end
|