
* Maxon C++ Library:
* Modul "files"
* Jens Gelhar 19.03.93, 17.04.94, 18.04.95

	xdef	_fopen,fopen__PCcPCc
	xdef	_freopen,freopen__PCcPCcP06stream
	xdef	_fclose,fclose__P06stream
	xdef	_allocstream,allocstream__Ui
	xdef	___Filelist
	xdef	_EXIT_1_close_sTiLl_open_files

	xref	_DOSBase,_std__in,_std__out,_std__err,_errno

Execbase	= 4
AllocMem	= -198
FreeMem	= -210

Open	= -30
Close	= -36
Seek	= -66
IoErr	= -132

str_mode	= 6
str_error	= 7
str_bufptr	= 8
str_flags	= 12
str_sizeof	= 13

buf_close	= 24


_EXIT_1_close_sTiLl_open_files:
	move.l	___Filelist,d0
	beq.b	_ex_std
	addq.l	#4,d0
	move.l	d0,-(a7)
	bsr	_fclose
	addq.l	#4,a7
	bra.b	_EXIT_1_close_sTiLl_open_files
_ex_std	pea	_std__out
	bsr	_fclose
	move.l	#_std__in,(a7)
	bsr	_fclose
	move.l	#_std__err,(a7)
	bsr	_fclose
	addq.l	#4,a7
	rts

_freopen:
freopen__PCcPCcP06stream:
	movem.l d2-d3/a6,-(a7)
	move.l	_DOSBase,a6
	move.l	3*4+12(a7),a0		; Stream-Struktur
	; testen: ist die Datei noch offen?
	move.l	(a0),d1
	beq.b	.ok1
	btst	#6,str_flags(a0)
	beq.b	.ok1			; darf geschlossen werden?
	jsr	Close(a6)		; ja, also zuerst schließen
.ok1	move.l	3*4+8(a7),a0		; Zugriffsart
	move.l	3*4+4(a7),d1		; Dateiname
	bsr	openfile
	tst.l	d0
	beq.b	err
	move.l	3*4+12(a7),a0
	move.l	d0,(a0)
	move.b	d1,str_mode(a0)
	bset	#6,str_flags(a0)
	clr.b	str_error(a0)
	move.l	a0,d0
	movem.l	(a7)+,d2-d3/a6
	rts

_fopen:
fopen__PCcPCc:	; Stack-Parameter: Filename, Accessmode
	movem.l d2-d3/a6,-(a7)
	move.l	_DOSBase,a6
	move.l	3*4+8(a7),a0		; Zugriffsart
	move.l	3*4+4(a7),d1		; Dateiname
	bsr.b	openfile
	tst.l	d0
	beq.b	err
	move.l	d1,-(a7)
	move.l	d0,-(a7)
	bsr.b	allocstream__Ui
	tst.l	d0
	beq.b	memerr
	move.l	d0,a0
	addq.l	#4,a7
	move.l	(a7)+,d1
	move.b	d1,str_mode(a0)		; Zugriffsart
fopRet	movem.l	(a7)+,d2-d3/a6
	rts

memerr:	; allocstream schlug fehl:
	move.l	_DOSBase,a6
	move.l	(a1)+,d1		; File wieder schließen
	jsr	Close(a6)
	addq.l	#4,a7
err:	; Datei nicht geöffnet:
	move.l	_DOSBase,a6
	jsr	IoErr(a6)
	move.l	d0,_errno
	moveq	#0,d0
	bra.b	fopRet

_allocstream:
allocstream__Ui:
	; Streamstruct für Filehandle 4(a7) allozieren
	movem.l	d2/a2/a6,-(a7)
	move.l	Execbase.w,a6
	moveq	#str_sizeof+4,d0
	move.l	#$10000,d1
	jsr	AllocMem(a6)
	tst.l	d0
	beq.b	ast1
	move.l	d0,a0
	addq.l	#4,d0
	move.l	3*4+4(a7),4(a0)          ; Filehandle eintragen
	move.b	#$C0,str_flags+4(a0)
	move.l	___Filelist,(a0)
	move.l	a0,___Filelist
ast1	movem.l	(a7)+,d2/a2/a6
	rts

openfile: ; Zugriffsart a0, Name d1: Filehandle nach d0, Modus (1=read, 2=write, 3 = rw) nach d1
	move.b	(a0)+,d0
	cmp.b	#'b',(a0)
	bne.b	noB
	addq.l	#1,a0
noB:	cmp.b	#'r',d0
	beq.b	fread
	cmp.b	#'w',d0
	beq.b	fwrite
	cmp.b	#'a',d0
	beq.b	fappend
	moveq	#0,d0
	rts
fread:	cmp.b	#'+',(a0)
	beq.b	freadwrite
	move.l	#1005,d2
	jsr	Open(a6)
	moveq	#1,d1
	rts

freadwrite:
	move.l #1005,d2
	jsr Open(a6)
	moveq #3,d1
	rts

fwrite:	cmp.b #'+',(a0)
	beq.b frwnew
fwnew:	move.l #1006,d2
	jsr Open(a6)
	moveq #2,d1
	rts

frwnew:	; neue Datei erzeugen für Lesen+schreiben:
	move.l #1006,d2
	move.l d1,-(a7)
	jsr Open(a6)
	move.l (a7)+,d1
	tst.l d0
	beq.b offen
	move.l d1,-(a7)
	move.l d0,d1
	jsr Close(a6)
	move.l (a7)+,d1
	move.l #1005,d2
	jsr Open(a6)
	moveq #3,d1
offen:	rts

fappend:
	cmp.b #'+',(a0)
	bne.b fapprw
	bsr.b fapprw
	moveq #3,d1
	rts
fapprw:	move.l d1,-(a7)
	move.l #1005,d2
	jsr Open(a6)
	move.l (a7)+,d1
	tst.l d0
	beq.b fwnew
	move.l d0,-(a7)
	move.l d0,d1
	moveq #0,d2
	moveq #1,d3
	jsr Seek(a6)
	move.l (a7)+,d0
	moveq #2,d1
	rts

_fclose:
fclose__P06stream:
	movem.l d1-d3/a0/a1/a6,-(a7)
	move.l 6*4+4(a7),d1
	subq.l #4,d1
	lea ___Filelist,a0
loop:	cmp.l (a0),d1
	beq.b found
	move.l (a0),d0
	beq.b notfound
	move.l d0,a0
	bra.b loop
notfound:	; Datei gibt's nicht offiziell:
	cmp.l #_std__in-4,d1
	beq.b found
	cmp.l #_std__out-4,d1
	beq.b found
	cmp.l #_std__err-4,d1
	beq.b found
	moveq #-1,d0
	bra.b fcret
found:	move.l d1,a1
	clr.l -(a7)
	btst #6,str_flags+4(a1)
	beq.b fc0
	move.l 4(a1),(a7)       ; Filehandle
fc0:	tst.b str_flags+4(a1)
	bpl.b fc1
	move.l (a1),(a0)        ; aus Liste aushängen
fc1:	move.l str_bufptr+4(a1),d0
	beq.b fc2
	; Puffer war eingerichtet:
	move.l a1,-(a7)
	move.l d0,a0
	move.l buf_close(a0),a6
	jsr (a6)
	move.l (a7)+,a1
fc2:	; Struct freigeben:
	tst.b str_flags+4(a1)
	bpl.b fc3
	moveq #str_sizeof+4,d0
	move.l Execbase.w,a6
	jsr FreeMem(a6)
fc3:	move.l (a7)+,d1
	beq.b fc4
	move.l _DOSBase,a6
	jsr Close(a6)           ; Datei endlich schließen
fc4:	moveq #0,d0
fcret:	movem.l (a7)+,d1-d3/a0/a1/a6
	rts

	SECTION D,DATA

___Filelist:	dc.l 0

	end

