include compiler.inc

	ttl	FOPEN, 1.05, 11-18-86 jwk

;open files for stream i/o. returns file pointer or NULL

	dseg
	exterr
	extrn _ftb:byte
	cseg
	xtfs	<open, lseek>

	procdef	fopen, <<path, ptr>, <mode, ptr>>
	locs	<<tmpm, word>, <hndl, word>, <rtv, ptr>>
	pushreg
	pushds
	xor	ax, ax
	moverr	ax
	gci	mode		;get HOW character
	caseb	'a',ap		;append
	caseb	'w',wr		;write
	caseb	'r',rd		;read
df:	stc			;signal bad return
	jmp short quit		;bad attribute, get out

rd:	mov	al, 1		;read
	jmp	short ckrtvl

wr:	mov	al, 2		;write
	jmp	short ckrtvl

ap:	mov	al, 10		;write + APPEND
;	jmp	ckrtvl

ckrtvl:	call	lopen		;local routine
	cmp	ax, 0
	jl	df		;error, return NULL
	mov	si, 5		;convert handle to pointer
	mul	si
	add	ax, offset _ftb
	svptr	ax, rtv, ds	;save return pointer value
	mov	ax, tmpm	;check APPEND bit
	and	al, 8
	jz	fini		;nope, done

	mov	ax, 2		;append needs seek to EOF
	sub	bx,bx
	callit	lseek,<<ax,reg>,<bx,reg>,<bx,reg>,<hndl,word>>

fini:	ldptr	si,rtv
	xor	ax,ax
	mov	word ptr 3[si], ax	;clear ERFLAG and CRFLG bytes
	dec	ax			;to EOF value
	mov	word ptr [si], ax	;erase ungetc() char
	mov	ax, tmpm		;get mode indicator
	and	ax,7			;mask to R, W, and RAW bits only
	mov	byte ptr 2[si], al	;set MODE byte
	clc				;signal successful return
quit:	retptrr	si,ds			;return pointer or NULL
	pend	fopen

ckh1:	caseb	'+',rwa		;set r/w access
	caseb	'b',mkraw	;set make-raw bit
;	jmp	ckhow		;ignore anything else
ckhow:	gci	mode		;check rest of string
	or	ax, ax		;was char EOS
	jnz	ckh1		;no, check it
	mov	ax, tmpm
	ret

mkraw:	mov	ax, tmpm	;set RAW bit
	or	al, 4
	mov	tmpm, ax
	jmp	ckhow

rwa:	mov	ax, tmpm	;set both R and W
	or	al, 3
	mov	tmpm, ax
	jmp	ckhow

lopen:	mov	tmpm, ax	;save mode
	call	ckhow		;get rest of line
	test	al,8		;check for appending
	jz	op1		;no
	or	al,3		;yes, open as r/w
op1:	dec	ax		;to standard C code
	callit	open,<<ax,reg>,<path,ptr>>
	mov	hndl, ax	;handle
	ret

	finish
