changeset 734:1cf59b6e12df

Brought over from NitrOS-9
author boisy
date Sun, 05 Jan 2003 23:11:52 +0000
parents 26d34f1c5aeb
children 98acb7c3a708
files level2/modules/pipeman.asm
diffstat 1 files changed, 360 insertions(+), 279 deletions(-) [+]
line wrap: on
line diff
--- a/level2/modules/pipeman.asm	Sun Jan 05 22:49:28 2003 +0000
+++ b/level2/modules/pipeman.asm	Sun Jan 05 23:11:52 2003 +0000
@@ -1,318 +1,399 @@
 ********************************************************************
-* PipeMan - Pipe file manager
+* PipeMan - NitrOS-9 Pipe File Manager
+*
+* Enhanced and re-written by Alan DeKok
+*
+* 'show grf.3.a | eat'  (eat is cat, but just does a I$ReadLn, and not I$WritLn)
+* April 10, 1996  14:05:15
+* April 10, 1996  14:07:47
+*          15.2 seconds per iteration
+*          i.e. everything but the screen writes
+* 
+* fast SCF+fast pipe
+* 'show grf.3.a | cat', 10 times
+* April 10, 1996  13:17:54
+* April 10, 1996  13:21:57
+*          24.3 seconds per iteration
+*          9.1 solely for pipes
+* 
+* fast SCF+old slow pipe
+* April 10, 1996  13:30:24
+* April 10, 1996  13:38:04
+*          46.0 seconds per iteration
+*          30.8 solely for pipes
+* 
+*          speedup percent is (30.8-9.1)/30.8 = 70%
+* 
+*          Pipes are more than doubled in speed!
+*
+* 32 byte read and write buffers
 *
 * $Id$
 *
 * Ed.    Comments                                       Who YY/MM/DD
 * ------------------------------------------------------------------
-* 4      Original OS-9 L2 Tandy distribution
-*        Added comments from Curtis Boyle's code        BGP 98/10/22
 
          nam   PipeMan
-         ttl   Pipe file manager
+         ttl   NitrOS-9 Pipe File Manager
 
-         ifp1  
+         ifp1
          use   defsfile
-         use   pipedefs
-         endc  
+         endc
 
-rev      set   $01
+tylg     set   FlMgr+Objct   
+atrv     set   ReEnt+Rev
+rev      set   $03
 edition  set   4
 
-         mod   eom,Name,FlMgr+Objct,ReEnt+rev,Start,0
+         mod   eom,name,tylg,atrv,start,size
+
+         rmb   $0000
+SIZE     equ   .
 
-Name     fcs   /PipeMan/
+         org   PD.FST
+PD.READ  rmb   4
+PD.WRITE rmb   4
+PD.END   rmb   2          end of the buffer
+PD.WPTR  rmb   2          write pointer
+PD.RPTR  rmb   2          read pointer
+PD.BLOCK rmb   1          0=block reads, 1=OK to read block flag
+
+         org   $0000
+P.CPR    rmb   1          process ID
+P.CNT    rmb   1          count
+P.SIG    rmb   1          signal code
+P.FLAG   rmb   1          raw/edit flag
+
+name     fcs   /PipeMan/
          fcb   edition
 
-Start    lbra  Create     Create, same as open
-         lbra  Open       Open
-         lbra  UnkSvc     MakDir
-         lbra  UnkSvc     ChgDir
-         lbra  UnkSvc     Delete
-         lbra  L0040      Seek
-         lbra  PRead      PRead
-         lbra  PWrite     PWrite
-         lbra  L00AB      PRdLn
-         lbra  L0105      PWrLn
-         lbra  L0040      GetStat
-         lbra  L0040      SetStat
-         lbra  Close      Return to system
+start    lbra  Create
+         lbra  Open
+         lbra  MakDir
+         lbra  ChgDir
+         lbra  Delete
+Seek     clrb
+         rts
+         nop
+         lbra  Read
+         lbra  Write
+         lbra  ReadLn
+         lbra  WritLn
+GetStt   clrb
+         rts
+         nop
+SetStt   clrb
+         rts
+         nop
+Close    lda   PD.CNT,y
+         bne   L008E
+         LDU   PD.BUF,y   if no one's using it,
+         clrb
+         inca
+         os9   F$SRtMem   return the memory
+         clrb
+         rts
 
-UnkSvc   comb             Exit with Unknown Service error
-         ldb   #E$UnkSvc
-         rts   
+L008E    leax  PD.READ,y
+         cmpa  PD.READ+P.CNT,y is the read count zero?
+         Beq   L009C
+
+         cmpa  PD.WRITE+P.CNT,y is the write count zero?
+         bne   L00A9
+         leax  PD.WRITE,y
 
-L0040    clrb             No error & return
+L009C    lda   P.CPR,x    get process ID that's reading/writing
+         beq   L00A9      if none
+         ldb   P.SIG,x    get signal code
+         beq   L00A9
+         clr   P.SIG,x
+         os9   F$Send     send a wake-up signal to the process
+L00A9    clrb  
          rts   
 
-* Open or create a Pipe
-Create         
-Open     ldu   PD.RGS,y   get Caller's register stack ptr
-         ldx   R$X,u      get pointer to pathname
-         pshs  y          preserve descriptor pointer
-         os9   F$PrsNam   is it legal?
-         bcs   L007B      no, exit with error
-         ldx   <D.Proc    get task #
-         ldb   P$Task,x
-         leax  -1,y       point to last character of pathname
-         os9   F$LDABX    get it
-         tsta             high bit terminated?
-         bmi   L0060      yes, go on
-         leax  ,y         point just past it
-         os9   F$PrsNam   parse it again
-         bcc   L007B      can't accept more data, return error
-L0060    sty   R$X,u      save updated path pointer to caller
-         puls  y          restore path dsc. ptr
-         ldd   #256       grab a page of memory for my buffer
-         os9   F$SRqMem
-         bcs   L007A      can't get memory, return error
-         stu   PD.BUF,y   save pointer to buffer
-         stu   <PD.NxtI,y save read pointer?
-         stu   <PD.NxtO,y save write pointer?
-         leau  d,u        point to end of buffer
-         stu   <PD.End,y  save the end pointer
-L007A    rts              return
-L007B    comb             Exit with Bad Pathname error
-         ldb   #E$BPNam
-         puls  y,pc
-
-* Close
-Close    lda   PD.CNT,y   any open images left?
-         bne   L008E      yes, go on
-         ldu   PD.BUF,y   No, get buffer pointer
-         ldd   #256       return it's memory to system
-         os9   F$SRtMem
-         bra   L00A9
-* Still stuff open to pipe
-* Check Read part of pipe
-L008E    cmpa  PD.RCT,y   Same as # images open to Read from pipe?
-         bne   L0096      No, go check Write images
-         leax  PD.RPID,y  Point to Read variables
-         bra   L009C      Send signal to reading process
-* Check Write part of pipe
-L0096    cmpa  PD.WCT,y   Same as # images open to Write to pipe?
-         bne   L00A9      No, exit without error
-         leax  PD.WPID,y  Point to Write variables
-
-* Send signal
-L009C    lda   ,x         Get Process # to send signal to
-         beq   L00A9      None, exit without error
-         ldb   2,x        get the signal code to send
-         beq   L00A9      None, exit without error
-         clr   2,x        Clear out signal code
-         os9   F$Send     Send to process
-L00A9    clrb             No error & exit
+MakDir   equ   *
+ChgDir   equ   *
+Delete   equ   *
+         comb  
+         ldb   #E$UnkSVC
          rts   
 
-* ReadLn entry point
-* Entry: Y=Path dsc. ptr
-L00AB    ldb   #$0D       Flag for ReadLn
-         stb   PD.REOR,y  Save as Not raw flag in Read area
-         bra   L00B3      Go read
+Create   equ   *
+Open     equ   *
+         ldx   R$X,u        get address of filename to open
+         pshs  y            save PD pointer
+         os9   F$PrsNam   parse /pipe
+         bcs   L007B        exit on error
+         ldx   <D.Proc      current process ptr
+         ldb   P$Task,x     get task number for call, below
+         leax  -$01,y       back up one character
+         os9   F$LDABX    get last character of the filename
+         tsta               check the character
+         bmi   L0060      if high bit set, it's OK
+         leax  ,y           point to next bit
+         os9   F$PrsNam   else parse name
+         bcc   L007B      if no error, it's a sub-dir, and we error out
+L0060    sty   R$X,u        save new pathname ptr
+         puls  y            restore PD pointer
+         ldd   #$0100
+         os9   F$SRqMem   request one page for the pipe
+         bcs   L007A        exit on error
+         stu   PD.BUF,Y     save ptr to the buffer
+         stu   <PD.WPTR,Y save write pointer
+         stu   <PD.RPTR,Y and read pointer
+         leau  d,u          point to the end of the buffer
+         stu   <PD.END,Y    save save the ptr
+L007A    rts   
 
-* Read entry point
-PRead    clr   PD.REOR,y  Raw mode on
-L00B3    leax  PD.RPID,y  point to Pipe Read variables
-         lbsr  L0160      Go wait for pipe to be ready for us
-         bcs   L0100      Error, shut off our side & signal other end of pipe
-         ldd   R$Y,u      get # bytes requested to read
-         beq   L0100      None, shut off our side & signal other end of pipe
-         ldx   R$X,u      get pointer to callers destination
-         addd  R$X,u
-         pshs  b,a
-         pshs  x          preserve start pointer
-         bra   L00D5
+L007B    comb  
+         ldb   #E$BPNam   bad path name
+         puls  pc,y
 
-* Read Loop for both ReadLn (stops on CR) or Read (stops when size is done)
-
-L00C8    pshs  x          Preserve buffer start ptr
-         leax  PD.RPID,y  Point to Read vars
-         lbsr  L018B      Go wait for possible data
-         bcc   L00D5      May be some, continue
-         puls  x          Restore buffer start ptr
-         bra   L00F1      None expected, exit with what we have
+ReadLn   ldb   #$0D
+         fcb   $21	skip one byte
 
-L00D5    ldx   <D.Proc    Get current process ptr
-         ldb   P$Task,x   Get task #
-         puls  x          Get Buffer start ptr
+Read     clrb
+         stb   PD.READ+P.FLAG,Y  raw read
+         leax  PD.READ,Y
+         lbsr  L0160      send wakeup signals to process
+         bcs   L0100      on error, wake up writing process
+         ldx   R$Y,U
+         beq   L0100      if no bytes to rwad
+         ldd   R$X,U      start address to read from
+         leax  d,x        add in number of bytes: end address
+
+* NOTE: PD.RGS,Y will change as the processes read/write the pipe,
+* and sleep.
+         pshs  u            save current caller's register stack
+         leas  -32,s        reserve a 32-byte buffer on the stack
+         leau  ,s           point to the start of the buffer
+         pshs  d,x        save start, end to read
 
-* Read from pipe buffer
-L00DB    lbsr  L01F2
-         bcs   L00C8
-         os9   F$STABX    Got byte, save it to caller
-         leax  1,x        Bump buffer ptr up
-         tst   PD.REOR,y  Check Read/ReadLn flag
-         beq   L00ED      Raw, skip ahead
-         cmpa  PD.REOR,y  Was the byte received a CR?
-         beq   L00F1      Yes, done reading
-L00ED    cmpx  ,s         Hit end of buffer read requested yet?
-         bcs   L00DB      No, keep reading
-L00F1    tfr   x,d        Move ptr to D
-         subd  ,s++       Calculate actual size read
-         addd  R$Y,u      ??? Add to size previously read???
-         std   R$Y,u      Save total # bytes read to caller
-         bne   L00FF      If some read, skip ahead
-         ldb   #E$EOF     Otherwise, exit with EOF error
-         bra   L0100
-L00FF    clrb             No error
+         clrb               no bytes read to user yet
+         puls  x            restore number of data bytes read, read address
+L00DB    bsr   L01F2        are we blocked?
+         bcs   L00C8        yes, send a signal
+         sta   b,u          store the byte in the internal read buffer
+         leax  $01,X        go up by one byte
+         incb               one more byte in the buffer
+         cmpb  #32          reached maximum size of the buffer?
+         blo   L00E0        no, continue
+         bsr   read.out     read 32 bytes of data to the caller
 
-L0100    leax  PD.RPID,y  Point to pipe Read vars
-         lbra  L01BD
-
-L0105    ldb   #$0D       Flag for WritLn (and terminator for lines)
-         stb   <PD.WEOR,y
-         bra   L010F      Go do the write
+L00E0    tst   PD.READ+P.FLAG,Y  was it a raw read?
+         beq   L00ED      skip ahead if raw
+         cmpa  #C$CR      was the character a CR?
+         beq   L00F1      yes, we're done: flush and exit
+L00ED    cmpx  ,S         or at end of data to read?
+         blo   L00DB        no, keep reading
 
-PWrite   clr   <PD.WEOR,y Flag for Raw Write
-L010F    leax  PD.WPID,y  Point to Write variables
-         lbsr  L0160      Go wait for pipe to be ready for us
-         bcs   L015C      Error, shut off our side & signal other end of pipe
-         ldd   R$Y,u      Get requested size to Write
-         beq   L015C      None, shut off our side & signal other end of pipe
-         ldx   R$X,u      Get ptr to data to write
-         addd  R$X,u      Calculate end of data ptr
-         pshs  b,a
-         pshs  x          Preserve start ptr
-         bra   L0131      Start writing
-L0124    pshs  x          Preserve current buffer ptr
-         leax  PD.WPID,y  Point to Write vars
-         lbsr  L018B      Go wait for data to be ready
-         bcc   L0131      Ready, go try writing again
-         puls  x          No more data, restore buffer ptr
-         bra   L0150      Go write out as much as we got
+L00F1    bsr   read.out     flush the rest of the pipe buffer to the user
+L00F2    tfr   X,D        this is how far we got
+         subd  ,S++       take out start of buffer
+         leas  32,s         kill our on-stack buffer
+         puls  u            restore caller's register stack ptr: NOT PD.RGS,Y
+         addd  R$Y,U      add in number of bytes
+         std   R$Y,U      save bytes read
+         bne   L00FF      if not zero
+         ldb   #E$EOF     zero bytes read:EOF error
+         fcb   $21          skip one byte
+
+L00FF    clrb               no errors
+L0100    leax  PD.READ,Y    read data ptr
+         lbra  L01BD      signal other it's OK to go ahead
+
+read.out pshs  a,x,y,u      save registers
+         tstb               any data to write?
+         beq   read.ex      no, skip ahead
+         clra               make 16-bit data length
+         tfr   d,y          number of data bytes to read to user
+         negb               make it negative
+         leax  b,x          back up TO pointer
+         pshs  x            save it
+         leax  ,u           point to the start of the buffer
+         ldu   <D.Proc      current process pointer
+         ldb   P$Task,u     A=$00 from above, already
+         puls  u            restore TO pointer
+
+         os9   F$Move       move the data over
+         clrb               no bytes read to the caller yet
+read.ex  puls  a,x,y,u,pc   restore registers and exit
 
-L0131    ldx   <D.Proc    Get process dsc. ptr
-         ldb   P$Task,x   Get task #
-         puls  x          Get start ptr back
-L0137    os9   F$LDABX    Get byte from caller
-         lbsr  L01CC
-         bcs   L0124
-         leax  1,x
-         tst   <PD.WEOR,y
-         beq   L014B
-         cmpa  <PD.WEOR,y
-         beq   L0150
-L014B    cmpx  ,s         Hit end of buffer?
-         bcs   L0137      No, keep writing
-         clrb             Yes, no error
-L0150    pshs  b,cc       Preserve error status
-         tfr   x,d        Move buffer ptr to D
-         subd  2,s        Calculate size actually written
-         addd  R$Y,u      Add to size previously written
-         std   R$Y,u      Save for caller
-         puls  x,b,cc     Restore error status
-L015C    leax  PD.WPID,y  Point to Write vars
-         bra   L01BD      Shut off Write part, send signal to Read part
+L00C8    pshs  x            save read pointer
+         bsr   read.out     dump data out to the user
+         pshs  b            save number of bytes read
+         leax  PD.READ,Y    read data area ptr
+         lbsr  L018B      setup for signal
+         puls  x,b          restore registers: note B=$00, but we CANNOT do a
+         bcc   L00DB        clrb, because this line needs CC.C!
+         bra   L00F2        don't write data out again, but exit
+
+* Check if we're blocked
+L01F2    lda   <PD.BLOCK,Y  we blocked?
+         bne   L01F9        no, skip ahead
+         coma               set flag: blocked
+         rts                and return to the caller
 
-* Make current process the process to Read or Write from Pipe, or wait in line
-*  until pipe is ready to for our process
-* Entry: Y=Path dsc. ptr
-*        X=Ptr to either Pipe Read or Pipe Write variables
-L0160    lda   ,x         Get process # that is reading or writing to pipe
-         beq   L0185      If none, make the current process the one
-         cmpa  PD.CPR,y   Same as current process using this path?
-         beq   L0189      Yes, no error & exit
-* A read or write request from the pipe was made from a process that is not
-* listed in the PD.??? pipe vars
-         inc   1,x        New process using pipe, update # processes using
-         ldb   1,x        Get new # of process reading or writing
-         cmpb  PD.CNT,y   Same as total # of processes using pipe? 
-         bne   L0173      No, skip ahead
-         lbsr  L009C      Yes, send signal from 2,x to process using pipe
-* New process is put in line to read/write to/from pipe
-L0173    os9   F$IOQu     Stick waiting process (A) into I/O Queue
-         dec   1,x        Dec # images in pipe down again
-         pshs  x          Preserve ptr
-         ldx   <D.Proc    Get current process dsc. ptr
-         ldb   <P$Signal,x Get last signal code from current process
-         puls  x          Get ptr back
-         beq   L0160      If it didn't receive the signal, try again
-         coma             Set carry & exit
+L01F9    pshs  x            save read ptr
+         ldx   <PD.RPTR,Y   where to read from in the buffer
+         lda   ,X+        get a byte
+         cmpx  <PD.END,Y  at the end of the buffer?
+         blo   L0207        no, skip ahesd
+         ldx   PD.BUF,Y   yes, go to start
+L0207    stx   <PD.RPTR,Y   save new read ptr
+         cmpx  <PD.WPTR,Y caught up to the write pointer yet?
+         bne   L0212        no, skeip ahead
+         clr   <PD.BLOCK,Y yes, set read is blocked
+L0212    andcc #^Carry      no errors
+         puls  pc,x         restore regs and exit
+
+L0160    lda   P.CPR,X      get current process
+         beq   L0185        none, exit
+         cmpa  PD.CPR,Y   current process ID
+         beq   L0189        none, exit
+         inc   P.CNT,X    one more process using this pipe
+         ldb   P.CNT,X
+         cmpb  PD.CNT,Y   same as the number for this path?
+         bne   L0173        no, skip ahead
+         lbsr  L009C      no, send a wake-up signal
+L0173    os9   F$IOQu     and insert it in the others IO queue
+         dec   P.CNT,X    decrement count
+         pshs  x
+         ldx   <D.Proc      current process ptr
+         ldb   <P$Signal,X  signal code
+         puls  x
+         beq   L0160      if no signal code sent, do another process
+         coma               otherwise return CC.C set, and B=signal code
          rts   
 
-L0185    ldb   PD.CPR,y   Get Current process #
-         stb   ,x         Save as process # that is reading/writing to pipe
-L0189    clrb             No error & exit
+L0185    ldb   PD.CPR,Y     grab current PD process
+         stb   P.CPR,X      save as current reading/writing process
+L0189    clrb               no errors
+         rts                and exit
+
+L01CC    pshs  b,x          save regs
+         ldx   <PD.WPTR,Y
+         ldb   <PD.BLOCK,Y 0=READ, 1=WRITE
+         beq   L01DE      was reading, set to write and continue
+         cmpx  <PD.RPTR,Y caught up to the read pointer yet?
+         bne   L01E3
+         comb  
+         puls  pc,x,b
+
+L01DE    inc   <PD.BLOCK,Y set to writing into the pipe
+L01E3    sta   ,X+        save the byte
+         cmpx  <PD.END,Y  if at the end of the buffer
+         blo   L01EC
+         ldx   PD.BUF,Y   reset to the beginning
+L01EC    stx   <PD.WPTR,Y
+         clrb  
+         puls  pc,x,b
+
+write.in pshs  a,x,y        save registers
+         leau  -32,u      point to the start of the buffer again
+         ldx   <D.Proc      current process pointer
+         lda   P$Task,x   get FROM task number for this process
+         ldx   1,s        get FROM pointer
+         ldy   #32        16 bytes to grab
+         clrb             TO the system task
+         os9   F$Move
+         ldb   #32        16 bytes in the buffer
+         puls  a,x,y,pc
+
+WritLn   ldb   #$0D
+         fcb   $21        skip one byte
+
+Write    clrb
+         stb   <PD.WRITE+P.FLAG,Y
+         leax  PD.WRITE,Y
+         bsr   L0160      make sure it's OK
+         bcs   L015C
+         ldx   R$Y,U      get number of bytes to write
+         beq   L015C
+         ldd   R$X,U      start address
+         leax  d,x        add in number of bytes
+         pshs  u
+         leau  ,s           point to the end of the buffer
+         leas  -32,s
+         pshs  d,x        save start, end
+
+         ldx   ,s           get initial start pointer
+         bsr   write.in     fill the write buffer
+
+         puls  x
+L0137    lda   ,u
+         bsr   L01CC      save it in the buffer
+         bcs   L0124      caught up to reading process yet?
+         leax  $01,X      up by one byte
+         leau  1,u
+         decb
+         bne   L0138
+         bsr   write.in     fill the buffer again
+
+L0138    tst   <PD.WRITE+P.FLAG,Y
+         beq   L014B
+         cmpa  #C$CR      at the end of a line to output?
+         beq   L014F
+L014B    cmpx  ,S         at end yet?
+         blo   L0137      if not, read more data
+L014F    clrb             clear carry and error
+L0150    ldu   2+32,s       skip END, 32-byte write buffer, get U
+         pshs  b,cc
+         tfr   X,D
+         subd  $02,S      take out end address
+         addd  R$Y,U      add in number of bytes
+         std   R$Y,U      save bytes written
+         puls  x,b,cc
+         leas  32,s         kill write buffer
+         puls  u
+
+L015C    leax  PD.WRITE,Y
+* can probably lose saving 'U' in next few lines... but only minor difference
+* Signal read/write it's OK to go ahead
+L01BD    pshs  u,b,cc
+         clr   P.CPR,X    NO process currently using this device
+         bsr   Other      signal other process to start
+         puls  pc,u,b,cc
+
+L0124    pshs  x,b
+         leax  PD.WRITE,Y
+         bsr   L018B      send signal to other
+         tfr   b,a          save error code, if applicable
+         puls  x,b          restore pointer, byte count
+         bcc   L0137        continue if OK
+         tfr   a,b          otherwise restore error code
+         bra   L0150        exit, returning the error code to the user
+
+L018B    ldb   P.CNT,X
+         incb  
+         cmpb  PD.CNT,Y
+         beq   L01B9
+         stb   P.CNT,X
+         ldb   #$01
+         stb   P.SIG,X
+         clr   PD.CPR,Y
+         pshs  x
+         bsr   Other
+         ldx   #$0000       make X=0
+         os9   F$Sleep    sleep forever
+         ldx   <D.Proc
+         ldb   <P$Signal,X  get signal code
+         puls  x
+         dec   P.CNT,X
+         tstb  
+         bne   L01BB      if a signal, we can't wake up
+         clrb             the writing process
          rts   
 
-L018B    ldb   1,x        Get # images [reading or writing] from pipe?
-         incb             Base 1
-         cmpb  PD.CNT,y   Same as # of open images?
-         beq   L01B9      Yes, Exit with Write Error
-         stb   1,x        Save updated # images
-         ldb   #$01       Wakeup signal
-         stb   2,x        Save as signal to send to process
-         clr   PD.CPR,y   Clear out current process # using pipe
-         pshs  x          Preserve read/write offset ptr
-         tfr   x,d        Move to D
-         eorb  #$04       Flip between read/write vars
-         tfr   d,x        Move to X
-         lbsr  L009C      Go send signal to process on other end of pipe
-         ldx   #$0000     Shut off process until signal received
-         os9   F$Sleep
-         ldx   <D.Proc    Get current process
-         ldb   <P$Signal,x Get last signal code received
-         puls  x          Restore read/write offset ptr
-         dec   1,x        Dec # open images
-         tstb             Was there a signal receieved?
-         bne   L01BB      Yes, exit with carry set
-         clrb             No error & exit
-         rts   
-L01B9    ldb   #E$Write   Write error
+L01B9    ldb   #E$Write   write error
 L01BB    coma  
          rts   
-* Shut off Read part, send signal to Write part
-* Shut down our side of pipe & send signal to other half of pipe
-L01BD    pshs  u,b,cc     Preserve U, error code & status
-         clr   ,x         Clear out process # using part of pipe
-         tfr   x,d        Move ptr to D
-         eorb  #$04       Flip between read/write vars
-         tfr   d,x        Move to X
-         lbsr  L009C      Send Signal to process on other end of pipe
-         puls  pc,u,b,cc  Restore error status & return
 
-* Entry: X=Ptr within caller's area we are writing from
-* A=Char to write
-* B=Task # of caller
-L01CC    pshs  x,b        Preserve ptr & Task #
-         ldx   <PD.NxtI,y Get ptr to next char in pipe buffer
-         ldb   <PD.RFlg,y Get data ready in pipe buffer flag
-         beq   L01DE      No data ready, skip ahead
-         cmpx  <PD.NxtO,y Meeting write buffer ptr?
-         bne   L01E3      No, continue
-         comb  
-         puls  pc,x,b
-* Put char into pipe buffer & Set flag that data is ready
-* Entry: Y=Path dsc. ptr
-*        A=Char to put in buffer
-L01DE    ldb   #1         Set flag
-         stb   <PD.RFlg,y Save it
-L01E3    sta   ,x+        Save char in pipe buffer
-         cmpx  <PD.End,y  Hit end of buffer?
-         bcs   L01EC      No, continue
-         ldx   PD.BUF,y   Yes, wrap to beginning
-L01EC    stx   <PD.NxtI,y Save current position in buffer
-         clrb  
-         puls  pc,x,b     Restore regs
-L01F2    lda   <Pd.RFlg,y
-         bne   L01F9
-         comb  
-         rts   
-L01F9    pshs  x
-         ldx   <PD.NxtO,y
-         lda   ,x+
-         cmpx  <PD.END,y
-         bcs   L0207
-         ldx   PD.BUF,y
-L0207    stx   <PD.NxtO,y
-         cmpx  <PD.NxtI,y
-         bne   L0212
-         clr   <Pd.RFlg,y
-L0212    andcc  #^Carry
-         puls  pc,x
+Other    exg   X,D
+         eorb  #$04       if r/w go to w/r
+         exg   D,X
+         lbra  L009C
 
-         emod  
+         emod
 eom      equ   *
-         end   
-
-
+         end