include	clib.inc
include	io.inc
include	stdio.inc
include errno.inc
include string.inc

PPROC	fread, buf:DPTR, rsize:word, num:word, fp:DPTR
local	p:DPTR
local	total:word
local	nbytes:word
local	nread:word
	push	si
	push	di
	MMOV	ax,word ptr buf+2
	MMOV	word ptr p+2,ax
	mov	ax,word ptr buf
	mov	word ptr p,ax
	mov	ax,rsize
	mul	num
	mov	total,ax
	mov	si,ax
	test	ax,ax
	jz	fread_END
	MLES	bx,fp
	mov	dx,es:[bx.iob_bufsize]
	mov	ax,es:[bx.iob_flag]
	and	ax,_IOMYBUF or _IONBF or _IOYOURBUF
	jnz	fread_00
	mov	dx,_MAXIOBUF
    fread_00:
	mov	di,dx
    fread_01:
	test	si,si
	jz	fread_BREAK
	MLES	bx,fp
	mov	ax,es:[bx.iob_flag]
	and	ax,_IOMYBUF or _IONBF or _IOYOURBUF
	jz	fread_02
	mov	ax,es:[bx.iob_cnt]
	test	ax,ax
	jz	fread_02
	cmp	si,ax
	jg	fread_01B
	mov	ax,si
    fread_01B:
	mov	nbytes,ax
	MPUSH	word ptr p+2
	push	word ptr p
	MPUSH	word ptr es:[bx.iob_bp+2]
	push	word ptr es:[bx.iob_bp]
	push	ax
	call	memcpy
	MLES	bx,fp
	mov	ax,nbytes
	sub	si,ax
	sub	es:[bx.iob_cnt],ax
	add	word ptr es:[bx.iob_bp],ax
	add	word ptr p,ax
	jmp	fread_01
    fread_02:
	mov	ax,si
	mov	cx,di
	cmp	ax,cx
	jb	fread_03
	test	cx,cx
	jz	fread_02A
	div	cx
	mov	ax,si
	sub	ax,dx
    fread_02A:
	mov     nbytes,ax
	push	es:[bx.iob_file]
	MPUSH	word ptr p+2
	push	word ptr p
	push	ax
	call	read
	mov	nread,ax
	MLES	bx,fp
	test	ax,ax
	jnz	fread_02B
	or	es:[bx.iob_flag],_IOEOF
	jmp	fread_02C
    fread_02B:
	cmp	ax,-1
	jne	fread_02D
	or	es:[bx.iob_flag],_IOERR
    fread_02C:
	mov	ax,total
	sub	ax,si
	div	rsize
	jmp	fread_END
    fread_02D:
	sub	si,ax
	add	word ptr p,ax
	jmp	fread_01
    fread_03:
	MPUSH	word ptr fp+2
	push	word ptr fp
	call	_filebuf
	cmp	ax,-1
	je	fread_02C
	MLES	bx,p
	mov	es:[bx],al
	inc	word ptr p
	dec	si
	MLES	bx,fp
	mov	ax,es:[bx.iob_bufsize]
	mov	di,ax
	jmp	fread_01
    fread_BREAK:
	mov	ax,num
    fread_END:
	pop	di
	pop	si
	ret
PEND	fread

	END
