include	clib.inc
include	io.inc
include	iost.inc

	public	oungetc

ifdef __TE__
	extrn	tiofread:near
endif

_TEXT	SEGMENT

oungetc	PROC	DIST
	push	si
	push	di
	mov	si,OSTDI
	xor	ax,ax
	cmp	ax,[si.ios_i]
	je	oungetc_02
    oungetc_00:
	dec	[si.ios_i]
	mov	ax,[si.ios_i]
	les	si,[si]
	add	si,ax
	inc	ax		; es:0 and ax 0 = ZF set
	mov	ah,0
	mov	al,es:[si]
    oungetc_01:
	pop	di
	pop	si
	ret
    oungetc_02:
  ifdef __TVEXE__
	test	[si.ios_flag],IO_MEMREAD
	jnz	oungetc_10
  endif
  ifdef __TE__
	test	[si.ios_flag],IO_LINEBUF
	jnz	oungetc_lb
  endif
	mov	cx,ax
	mov	dx,ax
	mov	ax,4201h
	mov	bx,[si.ios_file]
	int	21h		; current offset to DX:AX
	jc	oungetc_eof
    oungetc_03:
	mov	cx,[si.ios_c]	; last read size to CX
	test	dx,dx		; >= current offset ?
	jnz	oungetc_04
	cmp	cx,ax
	ja	oungetc_error	; stream not align if above
	je	oungetc_eof	; EOF == top of file
	cmp	ax,[si.ios_size]
	jne	oungetc_04
	cmp	dx,word ptr [si.ios_offset]
	jne	oungetc_04
	cmp	dx,word ptr [si.ios_offset+2]
	je	oungetc_eof
   oungetc_04:
	sub	ax,cx		; adjust offset to start
	sbb	dx,0
	mov	cx,[si.ios_size]
	jnz	oungetc_05
	cmp	cx,ax
	jae	oungetc_07
   oungetc_05:
	sub	ax,cx
	sbb	dx,0
   oungetc_06:
	push	cx
	push	dx
	push	ax
	mov	ax,SEEK_SET
	push	ax
	call	oseek
	pop	ax
	jz	oungetc_eof
	cmp	ax,[si.ios_c]
	ja	oungetc_error
	mov	[si.ios_c],ax
	mov	[si.ios_i],ax
	jmp	oungetc_00
    oungetc_07:
	mov	cx,ax
	xor	ax,ax
	cwd
	jmp	oungetc_06
    oungetc_error:
	or	[si.ios_flag],IO_ERROR
    oungetc_eof:
	mov	ax,-1
	xor	si,si
	jmp	oungetc_01
  ifdef __TVEXE__
    oungetc_10:
	lodm	[si.ios_offset]
	add	ax,[si.ios_c]
	adc	dx,0
	jmp	oungetc_03
  endif
  ifdef __TE__
    oungetc_lb:
	cmp	[si.ios_l],ax	; first line ?
	je      oungetc_eof
	inc     [si.ios_c]
	sub	[si.ios_l],2
	call	tiofread
	jz	oungetc_eof
	mov	ax,[si.ios_c]
	mov	[si.ios_i],ax
	jmp	oungetc_00
  endif
oungetc	ENDP

_TEXT	ENDS

	END
