;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
* $Id: nonvolatile.s 1.1 1999/02/03 04:10:45 jotd Exp $
**************************************************************************
*   NONVOLATILE-LIBRARY                                                  *
**************************************************************************
**************************************************************************
*   INITIALIZATION                                                       *
**************************************************************************



NONVINIT	move.l	_nonvbase(pc),d0
		beq	.init
		rts

.init		move.l	#162,d0		; reserved function
		move.l	#80,d1		; 20 variables: should be OK
		lea	_nonvname(pc),a0
		bsr	_InitLibrary
		lea	_nonvbase(pc),a0
		move.l	d0,(a0)
		move.l	d0,a0
		
		patch	_LVOGetCopyNV(a0),_GetCopyNV
		patch	_LVOStoreNV(a0),_StoreNV
		patch	_LVOGetNVInfo(a0),_GetNVInfo
		patch	_LVODeleteNV(a0),_DeleteNV
;		patch	_LVOGetNVList(a0),_GetNVList
		patch	_LVOFreeNVData(A0),FREENVDATA

		rts

;GetNVInfo[APTR d0](killrequesters [bool D1])
_GetNVInfo:
;	moveq	#0,D0	; not available

	moveq.l	#8+8,d0
	moveq.l	#0,d1
	bsr.w	ForeignAllocMem
	tst.l	d0
	beq.s	.rts
	move.l	d0,a0
	move.l	d0,(A0)+
	move.l	#8+8,(A0)+
	move.l	#999900,(A0)	;total storage on nv-device
	move.l	#989800,4(A0)	;free storage on nv-device
	move.l	a0,d0
.rts	rts


;GetCopyNV[APTR d0](appname[strptr a0],itemname[strptr a1],
;  killrequesters[bool d1])
;caveats: if appname+itemname becomes >32 chars the function will show
;  a requester indicating theres a problem within the function
;  (not likely as programmers chose them short to save NVRAM-space)
_GetCopyNV:
		link	a5,#-$40
;assemble filename, <appname>_<itemname>\0
		MOVEM.L	a0-a3,-(A7)
		lea.l	4*4+4(A7),a2

		bsr	assemble_filename

;check if file exists
		lea.l	4*4+4(A7),a0
		sub.l	a0,a2
		cmp.l	#32,a2
		bls.s	.filename_ok
		pea	_LVOGetCopyNV(pc)
		pea	_nonvname(pc)
		bra	_emufail

.filename_ok	move.l	_resload(pc),a2
		jsr	(resload_GetFileSize,a2)
		tst.l	d0
		beq.s	.notexisting

;reserve mem
		add.l	#$8+7,d0
		and.w	#$fff8,d0
		move.l	d0,4*4+4+$38(A7)
		clr.l	d1
		bsr.w	ForeignAllocMem
		tst.l	d0
		beq.s	.notexisting

;header:
		move.l	d0,a3
		move.l	d0,(A3)+
		move.l	4*4+4+$38(A7),d1
		move.l	d1,(A3)+

;load file into mem
		addq.l	#8,d0
		move.l	d0,a1
		lea.l	4*4+4(A7),a0
		move.l	_resload(pc),a2
		jsr	(resload_LoadFile,a2)

		move.l	a3,d0
		MOVEM.L	(A7)+,a0-a3
		unlk	a5
		rts

.notexisting	moveq	#0,D0
		MOVEM.L	(A7)+,a0-a3
		unlk	a5
		rts


;FreeNVData(data[APTR A0])

FREENVDATA
		move.l	a0,d0
		beq.s	.rts
		move.l	-8(A0),a1
		move.l	-4(A0),d0
		bsr.w	ForeignFreeMem

.rts		rts

;; DeleteNV [error - UWORD d0](appName[STRPTR a0], itemName[STRPTR A1], 
;   killRequesters[BOOL d1])

_DeleteNV:
		link	a5,#-$40
		MOVEM.L	a2-a3/d1,-(A7)
		lea.l	4*4+4(A7),a2

		bsr	assemble_filename

		lea.l	4*4+4(A7),a2

		move.l	_resload(pc),a3
		move.l	a2,a0
		jsr	resload_GetFileSize(a3)
		tst.l	d0
		beq.b	.out		; error

		IFD	NV_DELETE_FILES
		move.l	a2,a0
		jsr	resload_DeleteFile(a3)
		ELSE
		moveq	#-1,d0		; pretend that we succeeded in deletion
		ENDC
.out
		MOVEM.L	(a7)+,a2-a3/d1
		unlk	a5
		rts

;; StoreNV [error - UWORD d0](appName[STRPTR a0], itemName[STRPTR A1], 
;   data[APTR a2],length[ULONG d0], killRequesters[BOOL d1])


_StoreNV
		link	a5,#-$40
		MOVEM.L	a2/d0/d2-d3,-(A7)
		lea.l	4*4+4(A7),a2

		bsr	assemble_filename

;check if file exists
		lea.l	4*4+4(A7),a0
		sub.l	a0,a2
		cmp.l	#32,a2
		bls.s	.filename_ok
		pea	_LVOStoreNV
		pea	_nonvname
		bra	_emufail

.filename_ok
;save with dos to ensure to wipe out illegal pathnames
		move.l	a0,d1
		MOVE.L	#MODE_NEWFILE,D2
		BSR.W	_Open
		TST.L	D0
		beq.s	.err
		move.l	d0,a2
		move.l	d0,d1
		move.l	$c(A7),d2
		move.l	(A7),d3		;multiply len by 10
		lsl.l	#2,d3
		add.l	(A7),d3
		add.l	d3,d3
		bsr.w	_Write
					;ignore any error
		move.l	a2,d1
		bsr.w	_Close

.err		movem.l	(A7)+,a2/d0/d2-d3
		moveq	#0,D0
		unlk	a5
		rts


; < A0: appname
; < A1: itemname
; < A2: buffer
; JOTD: used by StoreNV and GetCopyNV to compute the item final filename
; assemble filename, <appname>_NV.dir/<itemname>\0

assemble_filename:
.cpappname	tst.b	(A0)
		beq.s	.endappname
		move.b	(A0)+,(A2)+
		bra.s	.cpappname

.endappname	
		lea	appname_extension(pc),A0
.cpext		tst.b	(A0)
		beq.s	.endext
		move.b	(A0)+,(A2)+
		bra.s	.cpext
.endext
.cpitemname	tst.b	(A1)
		beq.s	.enditemname
		move.b	(A1)+,(A2)+
		bra.s	.cpitemname

.enditemname	move.b	#0,(A2)+
		rts



;GetNVList[AppName A0](killrequesters [bool D1])

_GetNVList:
	illegal
	rts
	IFD	XXXXX
	link	a5,#-$40
	movem.l	D2-D3/A2-A3,-(A7)
	lea	4*4+4(A7),A2

	move.l	A0,A3		; appname
	lea	.null(pc),A1
	bsr	assemble_filename

	move.l	#MLH_SIZE,D0
	move.l	#MEMF_CLEAR,D1
	bsr	ForeignAllocMem
	move.l	D0,D3
	beq.b	.end
	move.l	D3,A1
	INITLIST

	
	move.l	#$400,D0
	move.l	#MEMF_CLEAR,D1
	bsr	ForeignAllocMem
	tst.l	D0
	beq.b	.end

	move.l	D0,D2		; buffer

	lea	4*4+4(A7),A0	; dirname
	move.l	D2,A1		; buffer
	move.l	_resload(PC),a2
	move.l	#$400,D0		; buffer size

	bsr	WHDListFiles

	; loop on files and insert them in the list

	move.l	D2,A2		; buffer
.atloop
	tst.b	(A2)
	beq.b	.end
	move.l	D3,A0		; list

; unfinished: got to allocate and add nodes as follows
; and to do the symmetrical free nv list
;
;   STRUCTURE NVEntry,0
;	STRUCT	nve_Node,MLN_SIZE
;	APTR	nve_Name
;	ULONG	nve_Size
;	ULONG	nve_Protection
;   LABEL NVENTRY_SIZE


	move.l	A2,A1		; node: filename
	bsr	_AddTail
.stz:
	move.b	(A2)+,D0
	bne.b	.stz
	bra.b	.atloop

;;	move.l	#$400,D0
;;	move.l	D2,A1		; buffer
;;	bsr	ForeignFreeMem

.end
	movem.l	(A7)+,D2-D3/A2-A3
	unlk	A5
	rts
.null:
	dc.b	0
	ENDC

appname_extension:
	dc.b	".nvd/",0
	cnop	0,4
