
;
; FORMAT
;	'SAND' , # of Sample.w, # Size of header.w,
;	[ HEADER.l ] * # Size of header
;	[ SAMPLES ]  (whatever memory they take)
;


MAXALL equ 64   ; allow 64 samples

	;
	; load a directory full of objects into a merged filehunk
	; record size information and stuff like that.
	; list of files to load is specified in musiclist.txt
	; by Andy Hook

	move.l	#$40000,d0
	lea	memsiz(pc),a0
	move.l	d0,(a0)
	bsr	allocatememory
	beq	failure0
	lea	memory(pc),a0
	move.l	d0,(a0)
	lea	posinfo(pc),a0
	move.l	d0,(a0)
	add.l	#8,(a0)			; (leave room for ID stuff)
	lea	memptr(pc),a0
	add.l	#MAXALL*4,d0		; room for x sound offset ptrs
	move.l	d0,(a0)
	lea	parsestart(pc),a0
	move.l	d0,(a0)
	move.l	memsiz(pc),d1		; d1 = max size to load
					; d0 = load-at address
	lea	listname(pc),a0		; a0 = name to load
	bsr	loadthis
	beq	failure
	lea	memsiz(pc),a0
	sub.l	d0,(a0)			; loaded to much?
	beq	failure
	bmi	failure
	lea	memptr(pc),a0
	add.l	d0,(a0)
	lea	audiostart(pc),a0
	move.l	memptr(pc),(a0)
	lea	parseend(pc),a0		; store stuff after the musiclist.txt
	move.l	memptr(pc),(a0)

1$	btst	#6,$bfe001
	beq	failure
	bsr	parsenext		; a0 = name to load next
	bmi	failure
	beq	donethat
	move.l	a0,-(a7)
	bsr	printname
	move.l	(a7)+,a0
	btst	#6,$bfe001
	beq	failure
	move.l	memsiz,d1		; d1 = max size to load
	move.l	memptr,d0		; d0 = load-at address
	bsr	loadthis
	beq	failure

	btst	#0,d0			; this shouldn't happen but...
	beq.s	3$
	addq.l	#1,d0
3$
	lea	memsiz(pc),a0
	sub.l	d0,(a0)
	beq	failure
	bmi	failure
	lea	memptr(pc),a0

	lea posinfo(pc),a2
	move.l (a2),a1
	move.l	(a0),d1
	sub.l audiostart(pc),d1		; (remember start)
	move.l d1,(a1)+
	move.l	(a0),d1
	add.l	d0,d1
	sub.l	audiostart(pc),d1	; (and end too...for the last one)
	move.l	d1,(a1)
	move.l a1,(a2)
	lea poscount(pc),a2
	add.w #1,(a2)
	cmp.w #MAXALL-4,(a2)		; (room for header)
	bcc  failure

	add.l	d0,(a0)
	bra.s	1$

donethat
	move.l	#MAXALL*4,d1		; D1 = size to save
	move.l	memory(pc),a0		; D0 = save start
	move.l	a0,d0
	move.l	#'SAND',(a0)+		; ID HEADER
	move.w	poscount(pc),(a0)+	; x = # of samples
	move.w	#$0040,(a0)+		; x = Header Size (1/4th)
	lea	savename(pc),a0		; A0 = name to save under
	bsr	saveopen		; + Write HEADER INFO
	beq	failure

	move.l	parseend(pc),d2		; d2 = start, WRITE BODY INFO
	move.l	memptr(pc),d3		; d3 = size
	sub.l	d2,d3
	bsr	savewrite
	bsr	saveclose

	bsr	freememory
	lea	error2(pc),a0
	bra	dumpmess

failure0
	lea	error0(pc),a0
	bra	dumpmess
failure	bsr	freememory
	lea	error1(pc),a0
	bra	dumpmess





parsenext
	clr.w	d0
	move.l	parsestart(pc),a1
	move.l	parseend(pc),a2
	lea	fastparse(pc),a3
						; skip white space
parse10	cmp.l	a1,a2				; done?
	beq.s	parse90
	move.b	(a1)+,d0
	tst.b	(a3,d0.w)
	beq.s	parse10

	lea	-1(a1),a0			; A0 = start of valid
						; skip to white space
parse20	cmp.l	a1,a2
	beq.s	parse90
	move.b	(a1)+,d0
	tst.b	(a3,d0.w)
	bne.s	parse20
	clr.b	-1(a1)				; tack on terminator

	lea	parsestart(pc),a2		; remember where I am
	move.l	a1,(a2)
	move.b	#1,d0
	rts					; A0 = ptr to next name
parse90	clr.b	d0
	rts

;
; this fast parse table is mostly in retaliation for a beserk discussion
; in the end of BYTE magazine about revamping ASCII "because its too hard
; to deal with adequately"....perhaps for Intel loser users who can't
; think in CISC type operations, like their excuses for a computer.
;
; The discussion pointed out aspects of ASCII, but didn't define them in
; terms or good or bad.
;
; 3 conditions can be quickly tested this way, -1, 0 or 1... EOF/JUNK/VALID...
;

fastparse	dc.b	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
		dc.b	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
		dc.b	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
		dc.b	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
		dc.b	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
		dc.b	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
		dc.b	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
		dc.b	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0


;----------------------------------------------------------------------------
AllocMem	equ	-30-168
FreeMem		equ	-30-180
allocatememory
						; D0 = memory size
	clr.l	d1				; D1 = Memory Type, ie 2=Chip
	move.l	4,a6
	jsr	AllocMem(a6)
	tst.l	d0				; D0 = 0 = Failed
	rts
freememory
	move.l	#$40000,d0
	move.l	memory(pc),a1
	move.l	4,a6
	jmp	FreeMem(a6)
;----------------------------------------------------------------------------

printname
	movem.l	a0/a1,-(a7)
	lea	loading(pc),a0
	bsr	dumpmess
	movem.l	(a7)+,a0/a1
	move.l	a1,d3
	move.l	a0,d1
	sub.l	d1,d3
	move.l	a0,d2
	bsr.s	dumpmess2
	lea	carriage(pc),a0
dumpmess
	moveq	#0,d3
	move.b	(a0)+,d3			; D3 = Length
	move.l	a0,d2				; D2 = What
dumpmess2
	move.l	4,a6				; Get EXEC
	lea	DosLibrary(pc),a1		; Open 'DOS.LIBRARY'
	moveq	#0,d0				;
	jsr	LVOOpenLibrary(a6)		;
	move.l	d0,a6				; A6 = DosBase
	jsr	LVOOutput(a6)			; Get LVOOutput Handle
	move.l	d0,d1				; D1 = Output Handle
	jmp	LVOWrite(a6)			; LVOWrite

;----------------------------------------------------------------------------

LVODelay	equ -30-168
LVODeviceProc	equ -30-144
LVOSeek		equ -30-36
LVOOutput	equ -30-30
LVOInput	equ -30-24
LVOWrite	equ -30-18
LVORead		equ -30-12
LVOClose	equ -30-6
LVOOpen		equ -30
LVOOpenLibrary	equ -30-522

Disable		equ -120		; (some other fun stuff)
Enable		equ -126
;AllocMem	equ -198
;FreeMem	equ -210

FindTask	equ -294		; name,a1
SetSignal	equ -306		; newSignal,signalSet,d0,d1
Wait		equ -318		; signalSet,d0
AllocSignal	equ -330		; Signalnum,d0
FreeSignal	equ -336		; signalNum,d0

PutMsg		equ -366		; PutMsg(port=a0,mess=a1);
WaitPort	equ -384		; WaitPort(port=a0);
GetMsg		equ -372		; GetMsg(port=a0);

OpenDevice	equ -444		; devName,unit,ioReq,flags(a0,d0/a1,d1
CloseDevice	equ -450		; ioRequest,a1
RawDoFmt	equ -522

loadthis				; D1 = Size, D0 = Start, A0 = Name
	lea	lsiz(pc),a1
	move.l	d1,(a1)+
	move.l	d0,(a1)+
	move.l	a0,(a1)
	move.l	4,a6			; Open DOS.LIBRARY
	lea	DosLibrary(pc),a1
	moveq	#0,d0
	jsr	LVOOpenLibrary(a6)
	move.l	d0,a6			; A6 = DOS.LIBRARY
	move.l	lnam(pc),d1		; D1 = Get FileName
	move.l	#1005,d2		; D2 = MODE_OLDFILE  LOAD
	jsr	LVOOpen(a6)		; Open the file
	move.l	d0,d4			; d4 is reserved as file ptr
	beq.s	saveerror		; (can use load error routine)
	move.l	lstart(pc),d2		; D2 = Start
	move.l	lsiz(pc),d3		; D3 = Size
	move.l	d4,d1			; D1 = File Pointer
	jsr	LVORead(a6)
	move.l	d0,-(a7)
	move.l	d4,d1			; FP
	jsr	LVOClose(a6)		; Close File
	move.l	(a7)+,d0		; D0 = Amount Loaded
	move.b	#1,d1			; (flag success)
	rts
saveerror:
	moveq	#0,d0
	rts

saveopen				; D1 = Size, D0 = Start, A0 = Name
	lea	lsiz(pc),a1
	move.l	d1,(a1)+
	move.l	d0,(a1)+
	move.l	a0,(a1)
	move.l	4,a6			; Open DOS.LIBRARY
	lea	DosLibrary(pc),a1
	moveq	#0,d0
	jsr	LVOOpenLibrary(a6)
	move.l	d0,a6			; A6 = DOS.LIBRARY
	move.l	lnam(pc),d1
	move.l	#1006,d2
	jsr	LVOOpen(a6)
	move.l	d0,d4			; d4 is reserved as file ptr
	beq.s	saveerror		; (can use load error routine)
	move.l	lstart(pc),d2		; D2 = Start
	move.l	lsiz(pc),d3		; D3 = Size
savewrite
	move.l	d4,d1			; D1 = File Pointer
	jmp	LVOWrite(a6)

saveclose
	move.l	d4,d1			; FP
	jmp	LVOClose(a6)		; Close File

lsiz		dc.l 0
lstart		dc.l 0
lnam		dc.l 0


DosLibrary	dc.b	'dos.library',0

poscount	dc.l 0
posinfo		dc.l 0

audiostart	dc.l 0
parsestart	dc.l 0
parseend	dc.l 0
memory		dc.l 0
memsiz		dc.l 0
memptr		dc.l 0
listname	dc.b 'musiclist.txt',0
		even
savename	dc.b 'music.hunk',0,0
		even
error2		dc.b 73-29+1,'Successfully loaded all musiclist.txt files!',10,0
		even
error1		dc.b 66-29+1,'File is missing, corrupt or too large',10,0
		even
error0		dc.b 73-29+1,'Could not allocate the $40000 Bytes I wanted',10,0
		even
loading		dc.b 10,'loading...',0,0
		even
carriage	dc.b 1,10,0

	end

; end of soundloader.s
