0
|
1 ********************************************************************
|
746
|
2 * PipeMan - OS-9 Level Two Pipe File Manager
|
734
|
3 *
|
941
|
4 * $Id$
|
|
5 *
|
734
|
6 *
|
|
7 * 'show grf.3.a | eat' (eat is cat, but just does a I$ReadLn, and not I$WritLn)
|
|
8 * April 10, 1996 14:05:15
|
|
9 * April 10, 1996 14:07:47
|
|
10 * 15.2 seconds per iteration
|
|
11 * i.e. everything but the screen writes
|
|
12 *
|
|
13 * fast SCF+fast pipe
|
|
14 * 'show grf.3.a | cat', 10 times
|
|
15 * April 10, 1996 13:17:54
|
|
16 * April 10, 1996 13:21:57
|
|
17 * 24.3 seconds per iteration
|
|
18 * 9.1 solely for pipes
|
|
19 *
|
|
20 * fast SCF+old slow pipe
|
|
21 * April 10, 1996 13:30:24
|
|
22 * April 10, 1996 13:38:04
|
|
23 * 46.0 seconds per iteration
|
|
24 * 30.8 solely for pipes
|
|
25 *
|
|
26 * speedup percent is (30.8-9.1)/30.8 = 70%
|
|
27 *
|
|
28 * Pipes are more than doubled in speed!
|
|
29 *
|
|
30 * 32 byte read and write buffers
|
0
|
31 *
|
|
32 * Ed. Comments Who YY/MM/DD
|
|
33 * ------------------------------------------------------------------
|
941
|
34 * 4 Enhanced and re-written ADK ??/??/??
|
0
|
35
|
|
36 nam PipeMan
|
746
|
37 ttl OS-9 Level Two Pipe File Manager
|
0
|
38
|
734
|
39 ifp1
|
0
|
40 use defsfile
|
734
|
41 endc
|
0
|
42
|
734
|
43 tylg set FlMgr+Objct
|
|
44 atrv set ReEnt+Rev
|
|
45 rev set $03
|
0
|
46 edition set 4
|
|
47
|
734
|
48 mod eom,name,tylg,atrv,start,size
|
|
49
|
|
50 rmb $0000
|
|
51 SIZE equ .
|
0
|
52
|
734
|
53 org PD.FST
|
|
54 PD.READ rmb 4
|
|
55 PD.WRITE rmb 4
|
|
56 PD.END rmb 2 end of the buffer
|
|
57 PD.WPTR rmb 2 write pointer
|
|
58 PD.RPTR rmb 2 read pointer
|
|
59 PD.BLOCK rmb 1 0=block reads, 1=OK to read block flag
|
|
60
|
|
61 org $0000
|
|
62 P.CPR rmb 1 process ID
|
|
63 P.CNT rmb 1 count
|
|
64 P.SIG rmb 1 signal code
|
|
65 P.FLAG rmb 1 raw/edit flag
|
|
66
|
|
67 name fcs /PipeMan/
|
0
|
68 fcb edition
|
|
69
|
734
|
70 start lbra Create
|
|
71 lbra Open
|
|
72 lbra MakDir
|
|
73 lbra ChgDir
|
|
74 lbra Delete
|
|
75 Seek clrb
|
|
76 rts
|
|
77 nop
|
|
78 lbra Read
|
|
79 lbra Write
|
|
80 lbra ReadLn
|
|
81 lbra WritLn
|
|
82 GetStt clrb
|
|
83 rts
|
|
84 nop
|
|
85 SetStt clrb
|
|
86 rts
|
|
87 nop
|
|
88 Close lda PD.CNT,y
|
|
89 bne L008E
|
|
90 LDU PD.BUF,y if no one's using it,
|
|
91 clrb
|
|
92 inca
|
|
93 os9 F$SRtMem return the memory
|
|
94 clrb
|
|
95 rts
|
0
|
96
|
734
|
97 L008E leax PD.READ,y
|
|
98 cmpa PD.READ+P.CNT,y is the read count zero?
|
|
99 Beq L009C
|
|
100
|
|
101 cmpa PD.WRITE+P.CNT,y is the write count zero?
|
|
102 bne L00A9
|
|
103 leax PD.WRITE,y
|
0
|
104
|
734
|
105 L009C lda P.CPR,x get process ID that's reading/writing
|
|
106 beq L00A9 if none
|
|
107 ldb P.SIG,x get signal code
|
|
108 beq L00A9
|
|
109 clr P.SIG,x
|
|
110 os9 F$Send send a wake-up signal to the process
|
|
111 L00A9 clrb
|
0
|
112 rts
|
|
113
|
734
|
114 MakDir equ *
|
|
115 ChgDir equ *
|
|
116 Delete equ *
|
|
117 comb
|
|
118 ldb #E$UnkSVC
|
0
|
119 rts
|
|
120
|
734
|
121 Create equ *
|
|
122 Open equ *
|
|
123 ldx R$X,u get address of filename to open
|
|
124 pshs y save PD pointer
|
|
125 os9 F$PrsNam parse /pipe
|
|
126 bcs L007B exit on error
|
|
127 ldx <D.Proc current process ptr
|
|
128 ldb P$Task,x get task number for call, below
|
|
129 leax -$01,y back up one character
|
|
130 os9 F$LDABX get last character of the filename
|
|
131 tsta check the character
|
|
132 bmi L0060 if high bit set, it's OK
|
|
133 leax ,y point to next bit
|
|
134 os9 F$PrsNam else parse name
|
|
135 bcc L007B if no error, it's a sub-dir, and we error out
|
|
136 L0060 sty R$X,u save new pathname ptr
|
|
137 puls y restore PD pointer
|
|
138 ldd #$0100
|
|
139 os9 F$SRqMem request one page for the pipe
|
|
140 bcs L007A exit on error
|
|
141 stu PD.BUF,Y save ptr to the buffer
|
|
142 stu <PD.WPTR,Y save write pointer
|
|
143 stu <PD.RPTR,Y and read pointer
|
|
144 leau d,u point to the end of the buffer
|
|
145 stu <PD.END,Y save save the ptr
|
|
146 L007A rts
|
0
|
147
|
734
|
148 L007B comb
|
|
149 ldb #E$BPNam bad path name
|
|
150 puls pc,y
|
0
|
151
|
734
|
152 ReadLn ldb #$0D
|
|
153 fcb $21 skip one byte
|
0
|
154
|
734
|
155 Read clrb
|
|
156 stb PD.READ+P.FLAG,Y raw read
|
|
157 leax PD.READ,Y
|
|
158 lbsr L0160 send wakeup signals to process
|
|
159 bcs L0100 on error, wake up writing process
|
|
160 ldx R$Y,U
|
|
161 beq L0100 if no bytes to rwad
|
|
162 ldd R$X,U start address to read from
|
|
163 leax d,x add in number of bytes: end address
|
|
164
|
|
165 * NOTE: PD.RGS,Y will change as the processes read/write the pipe,
|
|
166 * and sleep.
|
|
167 pshs u save current caller's register stack
|
|
168 leas -32,s reserve a 32-byte buffer on the stack
|
|
169 leau ,s point to the start of the buffer
|
|
170 pshs d,x save start, end to read
|
0
|
171
|
734
|
172 clrb no bytes read to user yet
|
|
173 puls x restore number of data bytes read, read address
|
|
174 L00DB bsr L01F2 are we blocked?
|
|
175 bcs L00C8 yes, send a signal
|
|
176 sta b,u store the byte in the internal read buffer
|
|
177 leax $01,X go up by one byte
|
|
178 incb one more byte in the buffer
|
|
179 cmpb #32 reached maximum size of the buffer?
|
|
180 blo L00E0 no, continue
|
|
181 bsr read.out read 32 bytes of data to the caller
|
0
|
182
|
734
|
183 L00E0 tst PD.READ+P.FLAG,Y was it a raw read?
|
|
184 beq L00ED skip ahead if raw
|
|
185 cmpa #C$CR was the character a CR?
|
|
186 beq L00F1 yes, we're done: flush and exit
|
|
187 L00ED cmpx ,S or at end of data to read?
|
|
188 blo L00DB no, keep reading
|
0
|
189
|
734
|
190 L00F1 bsr read.out flush the rest of the pipe buffer to the user
|
|
191 L00F2 tfr X,D this is how far we got
|
|
192 subd ,S++ take out start of buffer
|
|
193 leas 32,s kill our on-stack buffer
|
|
194 puls u restore caller's register stack ptr: NOT PD.RGS,Y
|
|
195 addd R$Y,U add in number of bytes
|
|
196 std R$Y,U save bytes read
|
|
197 bne L00FF if not zero
|
|
198 ldb #E$EOF zero bytes read:EOF error
|
|
199 fcb $21 skip one byte
|
|
200
|
|
201 L00FF clrb no errors
|
|
202 L0100 leax PD.READ,Y read data ptr
|
|
203 lbra L01BD signal other it's OK to go ahead
|
|
204
|
|
205 read.out pshs a,x,y,u save registers
|
|
206 tstb any data to write?
|
|
207 beq read.ex no, skip ahead
|
|
208 clra make 16-bit data length
|
|
209 tfr d,y number of data bytes to read to user
|
|
210 negb make it negative
|
|
211 leax b,x back up TO pointer
|
|
212 pshs x save it
|
|
213 leax ,u point to the start of the buffer
|
|
214 ldu <D.Proc current process pointer
|
|
215 ldb P$Task,u A=$00 from above, already
|
|
216 puls u restore TO pointer
|
|
217
|
|
218 os9 F$Move move the data over
|
|
219 clrb no bytes read to the caller yet
|
|
220 read.ex puls a,x,y,u,pc restore registers and exit
|
0
|
221
|
734
|
222 L00C8 pshs x save read pointer
|
|
223 bsr read.out dump data out to the user
|
|
224 pshs b save number of bytes read
|
|
225 leax PD.READ,Y read data area ptr
|
|
226 lbsr L018B setup for signal
|
|
227 puls x,b restore registers: note B=$00, but we CANNOT do a
|
|
228 bcc L00DB clrb, because this line needs CC.C!
|
|
229 bra L00F2 don't write data out again, but exit
|
|
230
|
|
231 * Check if we're blocked
|
|
232 L01F2 lda <PD.BLOCK,Y we blocked?
|
|
233 bne L01F9 no, skip ahead
|
|
234 coma set flag: blocked
|
|
235 rts and return to the caller
|
0
|
236
|
734
|
237 L01F9 pshs x save read ptr
|
|
238 ldx <PD.RPTR,Y where to read from in the buffer
|
|
239 lda ,X+ get a byte
|
|
240 cmpx <PD.END,Y at the end of the buffer?
|
|
241 blo L0207 no, skip ahesd
|
|
242 ldx PD.BUF,Y yes, go to start
|
|
243 L0207 stx <PD.RPTR,Y save new read ptr
|
|
244 cmpx <PD.WPTR,Y caught up to the write pointer yet?
|
|
245 bne L0212 no, skeip ahead
|
|
246 clr <PD.BLOCK,Y yes, set read is blocked
|
|
247 L0212 andcc #^Carry no errors
|
|
248 puls pc,x restore regs and exit
|
|
249
|
|
250 L0160 lda P.CPR,X get current process
|
|
251 beq L0185 none, exit
|
|
252 cmpa PD.CPR,Y current process ID
|
|
253 beq L0189 none, exit
|
|
254 inc P.CNT,X one more process using this pipe
|
|
255 ldb P.CNT,X
|
|
256 cmpb PD.CNT,Y same as the number for this path?
|
|
257 bne L0173 no, skip ahead
|
|
258 lbsr L009C no, send a wake-up signal
|
|
259 L0173 os9 F$IOQu and insert it in the others IO queue
|
|
260 dec P.CNT,X decrement count
|
|
261 pshs x
|
|
262 ldx <D.Proc current process ptr
|
|
263 ldb <P$Signal,X signal code
|
|
264 puls x
|
|
265 beq L0160 if no signal code sent, do another process
|
|
266 coma otherwise return CC.C set, and B=signal code
|
0
|
267 rts
|
|
268
|
734
|
269 L0185 ldb PD.CPR,Y grab current PD process
|
|
270 stb P.CPR,X save as current reading/writing process
|
|
271 L0189 clrb no errors
|
|
272 rts and exit
|
|
273
|
|
274 L01CC pshs b,x save regs
|
|
275 ldx <PD.WPTR,Y
|
|
276 ldb <PD.BLOCK,Y 0=READ, 1=WRITE
|
|
277 beq L01DE was reading, set to write and continue
|
|
278 cmpx <PD.RPTR,Y caught up to the read pointer yet?
|
|
279 bne L01E3
|
|
280 comb
|
|
281 puls pc,x,b
|
|
282
|
|
283 L01DE inc <PD.BLOCK,Y set to writing into the pipe
|
|
284 L01E3 sta ,X+ save the byte
|
|
285 cmpx <PD.END,Y if at the end of the buffer
|
|
286 blo L01EC
|
|
287 ldx PD.BUF,Y reset to the beginning
|
|
288 L01EC stx <PD.WPTR,Y
|
|
289 clrb
|
|
290 puls pc,x,b
|
|
291
|
|
292 write.in pshs a,x,y save registers
|
|
293 leau -32,u point to the start of the buffer again
|
|
294 ldx <D.Proc current process pointer
|
|
295 lda P$Task,x get FROM task number for this process
|
|
296 ldx 1,s get FROM pointer
|
|
297 ldy #32 16 bytes to grab
|
|
298 clrb TO the system task
|
|
299 os9 F$Move
|
|
300 ldb #32 16 bytes in the buffer
|
|
301 puls a,x,y,pc
|
|
302
|
|
303 WritLn ldb #$0D
|
|
304 fcb $21 skip one byte
|
|
305
|
|
306 Write clrb
|
|
307 stb <PD.WRITE+P.FLAG,Y
|
|
308 leax PD.WRITE,Y
|
|
309 bsr L0160 make sure it's OK
|
|
310 bcs L015C
|
|
311 ldx R$Y,U get number of bytes to write
|
|
312 beq L015C
|
|
313 ldd R$X,U start address
|
|
314 leax d,x add in number of bytes
|
|
315 pshs u
|
|
316 leau ,s point to the end of the buffer
|
|
317 leas -32,s
|
|
318 pshs d,x save start, end
|
|
319
|
|
320 ldx ,s get initial start pointer
|
|
321 bsr write.in fill the write buffer
|
|
322
|
|
323 puls x
|
|
324 L0137 lda ,u
|
|
325 bsr L01CC save it in the buffer
|
|
326 bcs L0124 caught up to reading process yet?
|
|
327 leax $01,X up by one byte
|
|
328 leau 1,u
|
|
329 decb
|
|
330 bne L0138
|
|
331 bsr write.in fill the buffer again
|
|
332
|
|
333 L0138 tst <PD.WRITE+P.FLAG,Y
|
|
334 beq L014B
|
|
335 cmpa #C$CR at the end of a line to output?
|
|
336 beq L014F
|
|
337 L014B cmpx ,S at end yet?
|
|
338 blo L0137 if not, read more data
|
|
339 L014F clrb clear carry and error
|
|
340 L0150 ldu 2+32,s skip END, 32-byte write buffer, get U
|
|
341 pshs b,cc
|
|
342 tfr X,D
|
|
343 subd $02,S take out end address
|
|
344 addd R$Y,U add in number of bytes
|
|
345 std R$Y,U save bytes written
|
|
346 puls x,b,cc
|
|
347 leas 32,s kill write buffer
|
|
348 puls u
|
|
349
|
|
350 L015C leax PD.WRITE,Y
|
|
351 * can probably lose saving 'U' in next few lines... but only minor difference
|
|
352 * Signal read/write it's OK to go ahead
|
|
353 L01BD pshs u,b,cc
|
|
354 clr P.CPR,X NO process currently using this device
|
|
355 bsr Other signal other process to start
|
|
356 puls pc,u,b,cc
|
|
357
|
|
358 L0124 pshs x,b
|
|
359 leax PD.WRITE,Y
|
|
360 bsr L018B send signal to other
|
|
361 tfr b,a save error code, if applicable
|
|
362 puls x,b restore pointer, byte count
|
|
363 bcc L0137 continue if OK
|
|
364 tfr a,b otherwise restore error code
|
|
365 bra L0150 exit, returning the error code to the user
|
|
366
|
|
367 L018B ldb P.CNT,X
|
|
368 incb
|
|
369 cmpb PD.CNT,Y
|
|
370 beq L01B9
|
|
371 stb P.CNT,X
|
|
372 ldb #$01
|
|
373 stb P.SIG,X
|
|
374 clr PD.CPR,Y
|
|
375 pshs x
|
|
376 bsr Other
|
|
377 ldx #$0000 make X=0
|
|
378 os9 F$Sleep sleep forever
|
|
379 ldx <D.Proc
|
|
380 ldb <P$Signal,X get signal code
|
|
381 puls x
|
|
382 dec P.CNT,X
|
|
383 tstb
|
|
384 bne L01BB if a signal, we can't wake up
|
|
385 clrb the writing process
|
0
|
386 rts
|
|
387
|
734
|
388 L01B9 ldb #E$Write write error
|
0
|
389 L01BB coma
|
|
390 rts
|
|
391
|
734
|
392 Other exg X,D
|
|
393 eorb #$04 if r/w go to w/r
|
|
394 exg D,X
|
|
395 lbra L009C
|
0
|
396
|
734
|
397 emod
|
0
|
398 eom equ *
|
734
|
399 end
|