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