
VERSION equ $0200

;
; Filename:     audio.asm
; Module name:  Audio
; Description:  coke board audio driver
;
; Commands:
;   Stop () - stop audio output
;   PlayTone (word pitch, word duration) - start playing tone
;
; Exports:
;   none
;
; Timers:
;   TIMER_Audio - timer for audio processing
;   
; Hooks:
;   HOOK_AUDIO - interrupt hook for audio processing
;
; Comments:
;   The audio driver will someday be able to play "song" files
;   and even wave files using PWM.  But in the meantime, it just
;   plays tones.
;
;   The Audio_Play functions are asychronous; that is, they
;   return immediately, and the sound plays in the backgound.
;   The audio driver installs itself into the audiohook, of
;   course.
;
;   There might be exported functions someday.
;
; History:
;   bv 9/14/98	- initial revision
;   bv 5/27/99 	- converted to cokeOS v3 module

	include	coke.inc

; EntryPoint

EntryPoint	subroutine
	cmpa	#CODE_INIT
	beq	.init
	cmpa	#CODE_FREE
	beq	.free
	rts
.init
	clc		; turn off audio output
	jsr	sys_audio
	clr	audio_playing	; say that nothing is playing
	ldx	#CommandTable	; install commands
	jsr	Coke_InstallCommandTable
	ldaa	#HOOK_AUDIO	; install hook function
	ldx	#HookFunction
	jsr	Coke_InstallHook
	rts		; ready to go!
.free
	ldaa	#HOOK_AUDIO	; remove hook function
	jsr	Coke_RemoveHook
	ldaa	#TIMER_Audio	; remove timer
	jsr	Coke_RemoveTimer
	ldx	#CommandTable	; remove commands
	jsr	Coke_RemoveCommandTable
	clc
	jsr	sys_audio	; stop audio output
	rts


; QueryVersion () returns the version string

Command_QueryVersion subroutine
	ldd	#VERSION
	jsr	Coke_MakeVersionString
	rts


; Stop () stops the currently playing sound, if there is one

Command_Stop subroutine
	tst	audio_playing	; is it currently playing?
	beq	.noplay	; if not, leave now
	clc		; turn off audio output
	jsr	sys_audio
	clr	audio_playing	; clear the playing flag
	ldaa	#TIMER_Audio	; remove the timer, if it's there
	jsr	Coke_RemoveTimer
.noplay
	ldaa	#COKE_ACK
	rts
	

; PlayTone (word pitch, word duration)
; starts playing a tone of a given pitch and duration.

Command_PlayTone subroutine
	clc
	jsr	sys_audio	; stop the current sound (why?)

	jsr	Coke_GetChar	; get lobyte pitch
	tab
	jsr	Coke_GetChar	; get hibyte pitch
	std	audiodelay	; store the pitch

	jsr	Coke_GetChar	; get lobyte duration
	tab
	jsr	Coke_GetChar	; get hibyte duration
	xgdy			; put duration in y
	ldx	#TimerFunction	; get timer address
	ldaa	#TIMER_Audio	; get timer id
	jsr	Coke_SetTimer	; set a timer

	sec
	jsr	sys_audio	; start the playing
	ldaa	#1
	staa	audio_playing	; say it is

	ldaa	#COKE_ACK
	rts


; HookFunction is called during the audio interrupt.  It is only
; called while the interrupt is active (sys_audio enables/disables
; the interrupt).  Right now, it does nothing, because playing tones
; doesn't require any interrupt processing...

HookFunction	subroutine
	rti


; TimerFunction is called after the desired duration.  When songs
; are implemented, this will play the next note in the song, but 
; right now it just stops the tone.

TimerFunction	subroutine
	psha

	clc
	jsr	sys_audio	; stop audio output
	clr	audio_playing	; clear the playing flag

	ldaa	#TIMER_Audio	; get the timer id
	jsr	Coke_RemoveTimer	; remove the timer function
	
	pula
	rts


; command table

CommandTable subroutine
	dc.b	CMD_Audio_QueryVersion
	dc.w	Command_QueryVersion
	dc.b	CMD_Audio_Stop
	dc.w	Command_Stop
	dc.b	CMD_Audio_PlayTone
	dc.w	Command_PlayTone
	
	dc.b	0


; data segment

audio_playing	ds 1
