include	clib.inc
include	errno.inc

PPROC	chsize, file_handle:WORD, new_size:DWORD
local	zbuf[512]:BYTE
local	offs_ax:WORD
local	offs_dx:WORD
local	count_ax:WORD
local	count_dx:WORD
	push	si
	push	di
	mov	ax,4201h	; save current offset
	mov	bx,file_handle
	xor	cx,cx
	mov	dx,cx
	int	21h
	jc	failed_00
	mov	offs_ax,ax
	mov	offs_dx,dx
	mov	ax,4202h	; seek to end of file
	sub	cx,cx
	mov	dx,cx
	int	21h
    failed_00:
	jc	failed
	cmp	dx,WORD PTR new_size+2
	ja	truncate
	jb	chsize_inc
	cmp	ax,WORD PTR new_size
	ja	truncate
	jb	chsize_inc
	jmp	seekback	; All done..
    chsize_inc:
	push	ax
	push	ss
	pop	es
	lea	di,zbuf
	xor	ax,ax
	mov	cx,512/2
	cld
	rep	stosw
	pop	ax
	mov	di,WORD PTR new_size
	mov	si,WORD PTR new_size+2
	sub	di,ax
	sbb	si,dx
	mov	count_dx,0
    write_loop:
	mov	count_ax,512
	cmp	si,count_dx
	jne	write_loop_00
	cmp	di,count_ax
    write_loop_00:
	jae	write_chunk
	mov	count_ax,di
	mov	count_dx,si
	or	di,di
	jz	seekback
    write_chunk:
	mov	cx,count_ax
	sub	di,cx
	sbb	si,count_dx
	lea	dx,zbuf
	push	ds
	push	ss
	pop	ds
	mov	ah,40h	; WRITE TO FILE OR DEVICE
	int	21h
	pop	ds
	jc	failed
	cmp	ax,cx
	je	write_loop
	mov	ax,ER_DISK_FULL
    failed:
	call	@dosmaper
	mov	ax,-1
	jmp	toend
    truncate:
	mov	ax,4200h	; Seek to new_size
	mov	dx,WORD PTR [new_size]
	mov	cx,WORD PTR [new_size+2]
	int	21h
	jc	failed
	mov	ah,40h
	xor	cx,cx	; Write zero byte at current file position
	int	21h
	jc	failed
    seekback:
	mov	dx,offs_ax
	mov	cx,offs_dx
	mov	ax,4200h
	int	21h
	jc	failed
	xor	ax,ax
    toend:
	pop	di
	pop	si
	ret
PEND	chsize

	END

