NEW
  AUTO 3,1
*--------------------------------------
PIPE.SRCBUF		.EQ ZPDRV
PIPE.DSTBUF		.EQ ZPDRV+2
PIPE.CNT		.EQ ZPDRV+4
PIPE.BASEH		.EQ ZPDRV+6
PIPE.BUFH		.EQ ZPDRV+7
PIPE.SIZEH		.EQ ZPDRV+8
*--------------------------------------
PIPE.OPEN		ldy #S.FD.PIPE.S
				lda (pFD),y
				inc
				sta (pFD),y

				lda IO.hFD
				clc
				rts
*--------------------------------------
PIPE.CLOSE		ldy #S.FD.PIPE.S
				lda (pFD),y
				bmi .1					remote PS closed its end

				lda #$80
				sta (pFD),y
				clc
				rts

.1				ldy #S.FD.PIPE.hMem
				lda (pFD),y
				beq .2

				>SYSCALL2 FreeStkObj

.2				jmp DEV.FreeFD
*--------------------------------------
* (pStack)+2	buf
* (pStack)+0	count
*--------------------------------------
PIPE.WRITE		ldy #S.FD.PIPE.S
				lda (pFD),y
				bpl .10

				jmp PIPE.eEOF			Remote PS closed the Pipe

.10				ldy #S.FD.PIPE.Free
				lda (pFD),y
				cmp (pStack)

				ldy #S.FD.PIPE.Free+1
				lda (pFD),y
				ldy #1
				sbc (pStack),y
				bcc PIPE.eNODATA		not enough room in PIPE

				ldy #S.FD.PIPE.Head+1
				jsr PIPE.GetBuf
				
				>STYA PIPE.DSTBUF

				>PULLA					get cnt lo
				sta PIPE.CNT
				eor #$ff
				tax

				>PULLA					get cnt hi
				sta PIPE.CNT+1
				eor #$ff
				pha 

				>PULLW PIPE.SRCBUF

				ldy #S.FD.PIPE.Head
				lda (pFD),y
				tay

				sta IO.SETWRITEAUX

.1				inx
				bne .2

				pla
				inc
				beq .8
				
				pha
				
.2				lda (PIPE.SRCBUF)
				sta (PIPE.DSTBUF),y

				inc PIPE.SRCBUF
				bne .4
				
				inc PIPE.SRCBUF+1
.4				iny
				bne .1
				
				lda PIPE.BUFH
				inc
				cmp PIPE.SIZEH
				beq .6
				
				sta PIPE.BUFH
				inc PIPE.DSTBUF+1
				bra .1
				
.6				stz PIPE.BUFH
				lda PIPE.BASEH			Pipe Buffer Base
				sta PIPE.DSTBUF+1
				bra .1
				
.8				sta IO.CLRWRITEAUX
				
				tya
				ldy #S.FD.PIPE.Head
				sta (pFD),y
				iny
				lda PIPE.BUFH
				sta (pFD),y
				ldy #S.FD.PIPE.Free
				jsr PIPE.SubCnt
			
				iny						#S.FD.PIPE.Used

				jsr PIPE.AddCnt
				jmp PIPE.EXIT

PIPE.eEOF		lda #MLI.E.EOF
				.HS 2C					BIT ABS
PIPE.eNODATA	lda #E.NODATA
				sec
				>RET 5
*--------------------------------------
PIPE.READ		ldy #S.FD.PIPE.Used+1
				lda (pFD),y				Data ?
				dey
				ora (pFD),y
				bne .10					yes...

				ldy #S.FD.PIPE.S
				lda (pFD),y
				bmi PIPE.eEOF			Remote PS closed the Pipe

				bpl PIPE.eNODATA
				
.10				ldy #S.FD.PIPE.Tail+1
				jsr PIPE.GetBuf

				>STYA PIPE.SRCBUF

				>PULLA					get cnt lo
				tax
				ldy #S.FD.PIPE.Used
				cmp (pFD),y

				>PULLA					get cnt hi
				pha
				iny						#S.FD.PIPE.Used+1
				sbc (pFD),y
				pla
				bcc .12					cnt < Used

				dey
				lda (pFD),y
				tax
				iny
				lda (pFD),y				X,A = Used

.12				stx PIPE.CNT
				sta PIPE.CNT+1

				eor #$ff
				pha
				txa
				eor #$ff
				tax

				>PULLW PIPE.DSTBUF	get dest buf

				ldy #S.FD.PIPE.Tail
				lda (pFD),y
				tay

				sta IO.SETREADAUX

.1				inx
				bne .2
				
				pla
				inc
				beq .8
				
				pha

.2				lda (PIPE.SRCBUF),y
				sta (PIPE.DSTBUF)

				inc PIPE.DSTBUF
				bne .4
				
				inc PIPE.DSTBUF+1
.4				iny
				bne .1
				
				lda PIPE.BUFH
				inc
				cmp PIPE.SIZEH
				beq .6
				
				sta PIPE.BUFH
				inc PIPE.SRCBUF+1
				bra .1
				
.6				stz PIPE.BUFH
				lda PIPE.BASEH
				sta PIPE.SRCBUF+1		Restore Pipe Buf base
				bra .1
	
.8				sta IO.CLRREADAUX
				
				tya
				ldy #S.FD.PIPE.Tail
				sta (pFD),y
				iny
				lda PIPE.BUFH
				sta (pFD),y
				ldy #S.FD.PIPE.Free
				jsr PIPE.AddCnt
			
				iny						#S.FD.PIPE.Used

				jsr PIPE.SubCnt

PIPE.EXIT		>LDYA PIPE.CNT			Y,A = bytes written
				inc pStack				Discard hFILE
				clc
				rts
*--------------------------------------
PIPE.GetBuf		lda (pFD),y
				sta PIPE.BUFH

				ldy #S.FD.PIPE.Size+1
				lda (pFD),y
				sta PIPE.SIZEH

				ldy #S.FD.PIPE.hMem
				lda (pFD),y
				
				>SYSCALL2 GetStkObjPtr

				sta PIPE.BASEH			Pipe Buffer Base
*				clc
				adc PIPE.BUFH
				rts
*--------------------------------------
PIPE.AddCnt		clc
				lda (pFD),y
				adc PIPE.CNT
				sta (pFD),y

				iny

				lda (pFD),y
				adc PIPE.CNT+1
				sta (pFD),y
				rts
*--------------------------------------
PIPE.SubCnt		sec 
				lda (pFD),y
				sbc PIPE.CNT
				sta (pFD),y

				iny

				lda (pFD),y
				sbc PIPE.CNT+1
				sta (pFD),y
				rts
*--------------------------------------
PIPE.EOF		clc
				ldy #S.FD.PIPE.Used
				lda (pFD),y
				iny
				ora (pFD),y
				beq .8

				lda #0
*				clc
				rts

.8				dec						lda #$ff
*				clc
				rts			
*--------------------------------------
MAN
SAVE usr/src/sys/kernel.s.pipe
LOAD usr/src/sys/kernel.s
ASM
