include	clib.inc
include	iost.inc

PPROC	ocopy,	len:DWORD
	push	si
	push	di
	mov	di,WORD PTR len
	mov	si,WORD PTR len+2
	test	si,si
	jnz	ocopy_start
	test	di,di
	jnz	ocopy_start	; copy zero byte -- ok
    ocopy_success:
	xor	ax,ax
	inc	ax
	jmp	ocopy_end
    ocopy_start:
	mov	ax,STDI.ios_c	; flush inbuf
	sub	ax,STDI.ios_i
	or	si,si
	jnz	ocopy_bigbuf
	cmp	ax,di
	jae	ocopy_inbuf
    ocopy_bigbuf:
	test	ax,ax
	jz	ocopy_block
    ocopy_inbuf:
	call	ogetc
	jz	ocopy_end
	call	oputc
	jz	ocopy_end
	sub	di,ax
	sbb	si,0
	mov	ax,si
	or	ax,di
	jz	ocopy_success	; success if zero (inbuf > len)
	mov	ax,STDI.ios_i
	cmp	ax,STDI.ios_c
	jne	ocopy_inbuf	; do byte copy from STDI to STDO
    ocopy_block:
	call	oflush		; flush STDO
	jz	ocopy_end	; do block copy of bytes left
	push	STDO.ios_size
	pushm	STDO.ios_bp
	movmx	STDO.ios_bp,STDI.ios_bp
	movmw	STDO.ios_size,STDI.ios_size
    ocopy_next:
	call	ofread
	jz	ocopy_eof
	mov	ax,STDI.ios_c	; count
	test	si,si
	jnz	ocopy_more
	cmp	ax,di
	jae	ocopy_last
    ocopy_more:
	sub	di,ax
	sbb	si,0
	mov	STDO.ios_i,ax	; fill STDO
	mov	STDI.ios_i,ax	; flush STDI
	call	oflush		; flush STDO
	jnz	ocopy_next	; copy next block
    ocopy_exit:
	mov	dx,ax
      ifdef __386__
      	pop	eax
        mov	STDO.ios_bp,eax
      else
	pop	ax
	mov	word ptr STDO.ios_bp,ax
	pop	ax
	mov	word ptr STDO.ios_bp+2,ax
      endif
	pop	ax
	mov	STDO.ios_size,ax
	mov	ax,dx
    ocopy_end:
	pop	di
	pop	si
	ret
    ocopy_last:
	mov	STDI.ios_i,di
	mov	STDO.ios_i,di
	call	oflush
	jmp	ocopy_exit
    ocopy_eof:
	xor	ax,ax
	test	si,di
	jnz	ocopy_exit
	inc	ax
	jmp	ocopy_exit
PEND	ocopy

	END
