;+asm
;do
;copy digi df1:
;*
;
; ### uB_Digitizer.asm by JM v 1.00 ###
;
; - Created 900620 by JM -
;
; Bugs: Who cares.
;
;
; Edited:
;
; - 900620 by JM -> v0.01	- code from DitigizerStuff.asm.
; - 900623 by JM -> v1.00	- works and looks somewhat nice.
;
;


		include	"bb.i"
		include	"exec/types.i"
		include	"exec/execbase.i"
		include	"exec/tasks.i"
		include	"exec/nodes.i"
		include	"exec/memory.i"
		include	"exec/io.i"
		include	"exec/strings.i"
		include	"exec/interrupts.i"
		include	"hardware/intbits.i"
		include	"devices/serial.i"
		include	"devices/console.i"
		include	"devices/timer.i"
		include	"devices/input.i"
		include	"devices/inputevent.i"
		include	"devices/keymap.i"
		include	"devices/audio.i"
		include	"libraries/dos.i"
		include	"libraries/dosextens.i"
		include	"intuition/intuition.i"
		include	"com.i"
		include	"relative.i"
		include	"util.i"
		include	"macros.i"
		include	"constants.i"
		include	"exec.xref"
		include	"hards.i"

		include	"debug.i"


		XREF	_LVOSetICR
		XREF	_LVOAbleICR
		XREF	_LVOAddICRVector
		XREF	_LVORemICRVector

_LVOAllocMiscResource	equ	-6
_LVOFreeMiscResource	equ	-12
MR_PARALLELPORT	equ	2

userport	equ	$bfe101
datadir		equ	$bfe301
mousebut	equ	$bfe001

HUGEMEM		equ	1000000000		-- never to be available --

		.var	global
		dlibb	Dos,Gfx,Intuition
		dlibb	MiscRes
		dl	input
		dl	ioreq,msgport
		dl	buffer,BUFFER,recorded
		dw	period,freq
		db	parport,audio

		.share	mem,#MEMF_CLEAR!MEMF_PUBLIC
		dm	ibuf[1024]

		.local
		.begin
		ra
		openlib	Dos[30],=cleanup
		share	mem,=cleanup

		call	Input
		move.l	d0,input
		beq	=cleanup

		moveq	#100,d7
		bsr	allocaudio
		bne	=cleanup

		moveq	#101,d7
		bsr	allocparallel
		bne	=cleanup

		moveq	#102,d7		no mem error
		move.l	#20000,d2
		call	Forbid
		 move.l	#MEMF_PUBLIC!MEMF_LARGEST,d1
		 fcall	AvailMem
		 sub.l	d2,d0
		 cmp.l	d2,d0
		 blt.s	=nomem
		 move.l	d0,BUFFER
		 move.l	#MEMF_PUBLIC,d1
		 fcall	AllocMem
		 move.l	d0,buffer
=nomem		fcall	Permit

		tst.l	buffer
		beq.s	=cleanup

		move.w	#10000,freq
		bsr	f2p

		bsr	do_something

=cleanup	bclr	#1,mousebut	turn filter on
		bsr	freeaudio
		bsr	freeparallel
		move.l	buffer,d0
		.if	ne
		 move.l	d0,a1
		 move.l	BUFFER,d0
		 call	FreeMem
		.end
		freesh	mem
		closlib	Dos
		move.l	d7,d0
		.end	begin
		.end	local



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

allocaudio	.local
		moveq.l	#MP_SIZE,d0		msgport for audio.device
		sub.l	a0,a0
		call	createport
		move.l	d0,msgport
		beq	=error

		moveq.l	#ioa_SIZEOF,d0		ioreq for opening audio.dev
		call	createio		createport -> port = d0,a0
		move.l	d0,ioreq
		beq.s	=error

		move.l	d0,a1			ioreq-structure
		lea.s	"audio.device",a0
		moveq.l	#0,d0			unit
		moveq.l	#0,d1			flags

		move.b	#127,LN_PRI(a1)		exclusive access
		lea.s	15,a2			all channels wanted
		move.l	a2,ioa_Data(a1)
		moveq.l	#1,d2
		move.l	d2,ioa_Length(a1)

		call	OpenDevice		open audio.device
		tst.l	d0
		bne.s	=error
		st	audio
		rts
=error		moveq	#1,d0			error = .ne
		rts


freeaudio	tst.b	audio			audio.device opened?
		.if	ne
		move.l	ioreq,a1
		call	CloseDevice		yea, close it
		.end
		move.l	msgport,a0
		call	deleteport
		move.l	ioreq,a0
		call	deleteio
		rts
		.end


allocparallel	.local
		move.l	#HUGEMEM,d0		kick out the parallel.device!
		move.l	d0,d2
		move.l	#MEMF_PUBLIC,d1
		call	AllocMem
		tst.l	d0
		beq.s	=notgot
		move.l	d0,a1
		move.l	d2,d0
		fcall	FreeMem

=notgot		lea.s	'misc.resource',a1
		moveq.l	#0,d0
		fcall	OpenResource
		move.l	d0,.MiscResBase
		beq	=error

		moveq.l	#MR_PARALLELPORT,d0
		lea.s	'YAAD_z_ere',a1
		move.l	.MiscResBase,a6
		jsr	_LVOAllocMiscResource(a6)

		tst.l	d0
		bne.s	=error
		st	parport
		move.b	d0,datadir		set port as input
		rts				.ne if error
=error		moveq	#1,d0
		rts
		.end



freeparallel	.local
		tst.b	parport
		beq.s	=done
		clr.b	datadir			set port as input
		moveq.l	#MR_PARALLELPORT,d0
		move.l	.MiscResBase,a6
		jsr	_LVOFreeMiscResource(a6)
=done		rts
		.end



f2p		move.l	#(3545000/2),d0
		divu.w	freq,d0
		move.w	d0,period
		rts


		.local
do_something	lea	fulltxt(pc),a0		full help
		bra.s	=doing
do_loop		lea	tinytxt(pc),a0		prompt
=doing		move.l	BUFFER,d0
		move.l	recorded,d1
		moveq	#0,d2
		move.w	freq,d2
		lea.s	"N",a1
		btst	#1,mousebut
		.if	ne
		 lea.s	"FF",a1
		.end
		move.l	a1,d3
		bsr	dpymsg

		move.l	input,d1
		move.l	ibuf,d2
		moveq	#127,d3
		call	Read
		move.l	d2,a0
		clr.b	-1(a0,d0.l)
		move.b	(a0)+,d0
		beq.s	do_loop
		cmp.b	#'a',d0
		.if	hs
		 cmp.b	#'z',d0
		 .if	ls
		  sub.b	#('a'-'A'),d0
		 .end
		.end

		lea.s	"QPRSLFT?",a1		known commands
		lea	=vectors-2(pc),a2
=find_cmd	addq.l	#2,a2
		move.b	(a1)+,d1
		beq.s	do_something		not found
		cmp.b	d1,d0
		bne.s	=find_cmd
		add.w	(a2),a2
		bsr	skipblk
		jmp	(a2)

**********************************************************************
=vectors	dptr	=quit
		dptr	=play
		dptr	=record
		dptr	=save
		dptr	=load
		dptr	=freq
		dptr	=pled
		dptr	=help
**********************************************************************

=quit		rts

=pled		bchg	#1,mousebut
		bra	do_loop

=help		lea	helptxt(pc),a0
		bra	=doing

=freq		moveq	#0,d1
=freq_lp	move.b	(a0)+,d0
		beq.s	=freq_ok
		sub.b	#'0',d0
		bmi.s	=freq_ok
		cmp.b	#9,d0
		bhi.s	=freq_ok
		cmp.w	#6000,d1
		bhi.s	=freq_e
		mulu.w	#10,d1
		add.w	d0,d1
		bcc.s	=freq_lp
=freq_e		lea.s	"Freq Error",LF,a0
		bsr	dpymsg
		bra	do_loop
=freq_ok	cmp.w	#100,d1
		blo.s	=freq_e
		cmp.w	#40000,d1
		bhi.s	=freq_e
		move.w	d1,freq
		bsr	f2p
		bra	do_loop

=save		move.l	a0,d1
		move.l	#MODE_NEWFILE,d2
		call	Open
		move.l	d0,d4			file*
		beq.s	=file_e
		move.l	d0,d1
		move.l	buffer,d2
		move.l	recorded,d3
		fcall	Write
		move.l	d0,d2			bytes written
		move.l	d4,d1			file*
		fcall	Close
		cmp.l	d2,d3			fully written?
		beq	do_something
=file_e		fcall	IoErr
		lea.s	"File Error %ld",LF,a0
		bsr	dpymsg
		bra	do_loop

=load		move.l	a0,d1
		move.l	#MODE_OLDFILE,d2
		call	Open
		move.l	d0,d4
		beq.s	=file_e
		move.l	d0,d1
		move.l	buffer,d2
		move.l	BUFFER,d3
		fcall	Read
		move.l	d0,recorded		set 'recorded' length
		move.l	d4,d1
		fcall	Close
		bra	do_something

skipblk_lp	addq.l	#1,a0
skipblk		move.b	(a0),d0
		cmp.b	#' ',d0
		beq.s	skipblk_lp
		cmp.b	#9,d0
		beq.s	skipblk_lp
		rts


initPaula	lea.l	Custom,a5
		lea	userport,a0
		lea	mousebut,a3
		moveq	#64,d0				; volume
		move.w	#%0000000010000000,d2		; int mask
		move.w	#128,d3				; offset
		move.w	#%0000000000001111,DMACON(a5)	; disable audio dma
		move.w	#%0000011110000000,INTENA(a5)	; disable audio ints
		move.w	period,AUD0PER(a5)		; set period
		move.w	d0,AUD0VOL(a5)			; set volume
		move.l	a1,AUD0LC(a5)			; bufptr
		move.w	period,AUD1PER(a5)		; set period
		move.w	d0,AUD1VOL(a5)			; set volume
		move.l	a1,AUD1LC(a5)			; bufptr
		move.w	#%1000000000000011,DMACON(a5)	; enable dma
		nop
		move.w	#%0000000000001111,DMACON(a5)	; disable it again
		rts



=play		.local
		call	Disable
		move.l	buffer,a1			; buffer pointer
		move.l	a1,a2				; end address
		add.l	recorded,a2			; add length
		bsr	initPaula
=playloop	move.b	(a1)+,d0
		move.b	d0,d1		; 4
		lsl.w	#8,d1
		move.b	d0,d1		; 4	; 16-bit sample
		move.w	d1,AUD0DAT(a5)	; 12
		move.w	d1,AUD1DAT(a5)	; 12
		cmp.l	a2,a1		; 6
		bhs.s	=endit		; 8
		btst	#6,(a3)		; 8	; button?
		beq.s	=endit		; 8
=waitti		move.w	INTREQR(a5),d0	; 12	; wait for an interrupt
		and.w	d2,d0		; 4
		beq.s	=waitti		; 8/10
		move.w	d2,INTREQ(a5)	; 12	; clear it
		bra.s	=playloop	; 8
=endit		fcall	Enable
		bra	do_loop
		.end

=record		.local
		call	Disable
		move.l	buffer,a1			; buffer pointer
		move.l	a1,a2				; end address
		add.l	BUFFER,a2			; add length
		bsr	initPaula
=recordloop	move.b	(a0),d0		; n
		sub.b	d3,d0		; 4
		move.b	d0,d1		; 4
		lsl.w	#8,d1		; 22
		move.b	d0,d1		; 4	; 16-bit sample
		move.w	d1,AUD0DAT(a5)	; 12
		move.w	d1,AUD1DAT(a5)	; 12
		move.b	d0,(a1)+	; 8	; save sample
		cmp.l	a2,a1		; 6
		bhs.s	=endit		; 8
		btst	#6,(a3)		; 8	; button?
		beq.s	=endit		; 8
=waitti		move.w	INTREQR(a5),d0	; 12	; wait for an interrupt
		and.w	d2,d0		; 4
		beq.s	=waitti		; 8/10
		move.w	d2,INTREQ(a5)	; 12	; clear it
		bra.s	=recordloop	; 8
=endit		sub.l	buffer,a1		; sample length
		move.l	a1,recorded
		fcall	Enable
		bra	do_loop
		.end

		.end	local



dpymsg		.local
		;a0=fmstr, d0..d7=args
		push	d0-d7/a0-a3
		move.l	sp,a1
		lea.l	=c(pc),a2
		move.l	ibuf,a3
		call	RawDoFmt
		call	Output
		move.l	d0,d1
		.if	ne
		move.l	a3,d2
		.do
		tst.b	(a3)+
		.while	ne
		subq.w	#1,a3
		move.l	a3,d3
		sub.l	d2,d3
		fcall	Write
		.end
		pull	d0-d7/a0-a3
		rts
=c		move.b	d0,(a3)+
		rts
		.end



helptxt		dc.b	'Yet Another Digitizer for the Amiga by J.Marin 1990',LF,LF
fulltxt		.text	nonull
Commands:
R		Record		(%ld)
P		Play		(%ld)
L <name>	Load
S <name>	Save
F <value>	Sampling Freq.	(%ld)
T		Toggle filter	(O%s)
Q		Quit the program
\		.end
tinytxt		dc.b	'YADA> '0


		.purge

		end


