******************************************************************
*								 *
*    Beep. By David Jenkins					 *
*								 *
******************************************************************

 	nolist
          include  "exec/types.i"
          include  "exec/io.i"
          include  "exec/libraries.i"
          include  "exec/memory.i"
          include  "exec/execbase.i"
          include  "offsets/rom.ofs"
	  include  "devices/audio.i"	
	list
 
sysbase	equ	4
* 
* Get space for variables
	bra	start
	dc.b	'Beep 1.03'
	dc.b	'25/Jan/89'
start
	moveq	#5,d6
	moveq	#5,d5
	cmpi.b	#10,(a0)	any data
	beq	noparm		no	
	move.b	(a0),d6		pitch
	cmpi.b	#10,1(a0)	any data
	beq	noparm		no
	move.b	2(a0),d5	duration

noparm
	movea.l	4,a6			exec base
	move.l  #lengthvar,d0		size of structure
	move.l  #MEMF_CLEAR+MEMF_PUBLIC,d1 memory type = CLEAR and PUBLIC
	jsr     AllocMem(a6)	call AllocMem
	move.l	d0,a5		keep it
	bne	ok1
	moveq	#8,d0
	rts

** get port space for audio device
ok1
	movea.l	4,a6			exec base
	moveq   #MP_SIZE,d0		size of structure
	move.l  #MEMF_CLEAR+MEMF_PUBLIC,d1 memory type = CLEAR and PUBLIC
	jsr     AllocMem(a6)	call AllocMem

	move.l  d0,audioport(a5)	save  Port
	bne	gotsp
	moveq	#8,d0
	rts			Big trouble. give up


** fill in audio port fields 

gotsp	movea.l	audioport(a5),a1
	move.b  #NT_MESSAGE,LN_TYPE(a1) LN_TYPE = NT_MESSAGE(5)
	move.l	#audioportname,LN_NAME(a1)	name

* allocate a signal bit

        move.l  sysbase,a6      Exec Lib Ptr
	moveq.l	#-1,d0			any signal will do
	jsr	AllocSignal(a6)
	moveq.l	#0,d1			convert signum to a mask
	bset.l	d0,d1
	move.l	d1,d7			stash  sig bit

	movea.l	audioport(a5),a1
	move.b	d0,MP_SIGBIT(a1)	save signal bit

* Find what task we are in, and install it in the msg ports

	sub.l   a1,a1           my task
        jsr     FindTask(a6)
	movea.l	audioport(a5),a1
	move.l	d0,MP_SIGTASK(a1)	task pointer


** add  ports

        move.l   audioport(a5),a1     Message Port
        jsr      AddPort(a6)   Add another Port to list

** Set up audio IOReq structures
	

	lea	audioreq(a5),a1	audio IORequest
	move.b  #NT_MESSAGE,LN_TYPE(a1) LN_TYPE = NT_MESSAGE(5)
	move.b  #0,LN_PRI(a1) 	LN_PRI = 0
	move.l  audioport(a5),MN_REPLYPORT(a1) move in message port pointer


** open audio device 


* allocate a channel

	lea	audioreq(a5),a1		IOReq
	move.b	#90,LN_PRI(a1)		set priority
	move.l	#channel,ioa_Data(a1) 	ask for channel
	move.l	#4,ioa_Length(a1)	set length to do allocate
	move.w	#ADCMD_ALLOCATE,IO_COMMAND(a1) get channel

	lea	audioname,a0		audio device name
	moveq	#0,d0			unit number		
	lea	audioreq(a5),a1		IOReq
	moveq	#0,d1			flags
	jsr	OpenDevice(a6)	
	lea	audioreq(a5),a1		IOReq
	cmpi.b	#0,IO_ERROR(a1)		ok?
	beq.s	beepset			yes
	moveq	#0,d0
	move.b	IO_ERROR(a1),d0
	rts

* set up for beep

beepset	move.l  #2,d0		size of buffer
	move.l  #MEMF_CLEAR+MEMF_CHIP,d1 chip memory 
	JSR     AllocMem(a6)	call AllocMem
	tst.l	d0		got memory?
	beq	nomem		no
	movea.l	d0,a4		keep memory address
	move.w	#$7f81,0(a4)	nice square wave

redo	lea	audioreq(a5),a1		IOaudio
	move.b	#ADIOF_PERVOL,IO_FLAGS(a1) new period and volume
	move.l	a4,ioa_Data(a1)		data
	move.l	#2,ioa_Length(a1)	length
	moveq	#0,d0
	moveq	#0,d1
	move.b	d6,d0
	and.b	#$f,d0
	bne.s	1$
	move.b	#5,d0
1$	move.b	d0,d1	
	mulu	#1000,d0
	move.w	d0,ioa_Period(a1)	set period
	moveq	#0,d0
	move.b	d5,d0
	and.b	#$f,d0
	bne.s	2$
	move.b	#5,d0
2$	mulu	#100,d0
	divu	d1,d0			calculate cycles
	move.w	#64,ioa_Volume(a1)	loud
	move.w	d0,ioa_Cycles(a1)	how long
	move.w	#CMD_WRITE,IO_COMMAND(a1) write
	BEGINIO
	

	move.l	d7,d0			wait for signal
	jsr	Wait(a6)		call wait

getnext	move.l	audioport(a5),a0	get message form audio port
	movea.l	4,a6		set Exec base
	jsr     GetMsg(A6)	call GetMsg
	tst.l	d0		any more?
	bne.s	getnext		yes

	lea	audioreq(a5),a1
	move.b	#0,IO_FLAGS(a1)
	move.w	#ADCMD_WAITCYCLE,IO_COMMAND(a1) wait for end
	BEGINIO

	move.l	d7,d0			wait for signal
	jsr	Wait(a6)		call wait


getnext2 move.l	audioport(a5),a0	get message form audio port
	movea.l	4,a6		set Exec base
	jsr     GetMsg(A6)	call GetMsg
	tst.l	d0		any more?
	bne.s	getnext2	yes

	lea	audioreq(a5),a1
	move.b	IO_ERROR(a1),ret(a5)

	moveq	#0,d0
	move.b	MP_SIGBIT+audioreq(a5),d0
	JSR     FreeSignal(A6)		FreeSignal

	movea.l a4,a1	audio data
	moveq   #2,D0	size of structure
	jsr     FreeMem(A6)	call FreeMem


nomem	lea	audioreq(a5),a1	audio IORequest
	JSR     CloseDevice(a6)	call CloseDevice

bye     movea.l  audioport(a5),a1  	Remove the timer Port
        jsr      RemPort(a6)

	movea.l audioport(a5),a1	audio port
	moveq   #MP_SIZE,D0	size of structure
	jsr     FreeMem(A6)	call FreeMem

	moveq	#0,d0
	move.b	ret(a5),d2
	move.l	a5,a1
	move.l  #lengthvar,D0	size of structure
	jsr     FreeMem(A6)	call FreeMem
	move.l	d2,d0
	rts

	cnop	0,4
channel	dc.l	$01020408

	cnop	0,4
audioname dc.b	'audio.device',0

	cnop	0,4
audioportname dc.b 'Audiodj',0
		
		offset 0
startvar
audioreq	ds.b	ioa_SIZEOF
audioport	ds.l	1		port address
ret		ds.b	1
lengthvar	equ	*-startvar
		end
