/**************************************************************************** * * * NDSAUDIO * * * * Copyright (c) 2009, Mukunda Johnson (mukunda@mukunda.com) * * * * Permission to use, copy, modify, and/or distribute this software for any * * purpose with or without fee is hereby granted, provided that the above * * copyright notice and this permission notice appear in all copies. * * * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *--------------------------------------------------------------------------* ****************************************************************************/ #define breakp mov r11,r11 .equ FIFO_CHANNEL, 8 //----------------------------------------------------------------------------- .bss .align //----------------------------------------------------------------------------- .equ FIFO_SIZE, 128 .equ FIFO_MASK, 127 .equ FIFO_SHIFT, 7 .equ SD9_MSGCOUNTER, 72 fifo: .space FIFO_SIZE fifoPosition: .space 4 // read .space 4 // write .global nasFifoInitMode nasFifoInitMode: .space 1 //----------------------------------------------------------------------------- .text .thumb .align //----------------------------------------------------------------------------- .macro public typ name .global \name .thumb_func \name: .endm .macro function name .thumb_func \name: .endm /****************************************************************************** * void nasOnData( int numBytes, void *userdata ) * * fifo data handler * numBytes is multiple of 4 ******************************************************************************/ public function nasOnData //----------------------------------------------------------------------------- add r0, #3 //; ensure multiple of 4 lsr r0, #2 // lsl r0, #2 // bne 1f // no data (???) bx lr 1: push {r4,r5,lr} //; preserve reg(s), and save stack offset //----------------------------------------------------------------------------- mov r1, r0 //; read data to stack lsr r4, r0, #2 //; r4 = wordcount (save this!) neg r0, r0 // add sp, r0 // mov r0, #FIFO_CHANNEL // mov r2, sp // bl fifoGetDatamsg // //----------------------------------------------------------------------------- ldr r0, [sp] //; test for nonbuffered message lsl r0, #25 //; bcs nonbuffered_message //; //----------------------------------------------------------------------------- //; r1 = fifo address ldr r1,=fifo //; r2 = variables ldr r2,=fifoPosition //; r3 = fifo write offset ldr r3, [r2, #4] //; r4 = word count ldr r5,=FIFO_MASK //; r5 = mask for fifo offset //----------------------------------------------------------------------------- 1: pop {r0} //; copy data into fifo str r0, [r1, r3] // add r3, #4 // and r3, r5 // sub r4, #1 // bne 1b // //----------------------------------------------------------------------------- str r3, [r2, #4] //; save new write position //----------------------------------------------------------------------------- pop {r4,r5} //; return... pop {r0} // mov lr, r0 // //----------------------------------------------------------------------------- ldr r0,=nasFifoInitMode //; init mode: process fifo data immediately ldrb r1, [r0] // cmp r1, #0 // beq 1f // mov r1, #0 // strb r1, [r0] // b nasProcessFifo // //----------------------------------------------------------------------------- 1: bx lr // //----------------------------------------------------------------------------- nonbuffered_message: //----------------------------------------------------------------------------- @ r0 = message << 25 @ r4 = wordcount @ sp = data @------------------------------------------------------------------------------ lsr r0, #25-2 @ jump to message handler adr r1, nb_jump_table @ ldr r1, [r1, r0] @ mov r0, sp @ bl .jump1 @ @------------------------------------------------------------------------------ lsl r4, #2 @ return add sp, r4 @ pop {r4,r5} @ pop {r1} @ .jump1: bx r1 @ .align nb_jump_table: .word nadSetChannelRegister // 80 .word nadSetChannelVolume // 81 .word nadSetChannelPanning // 82 .word nadSetChannelDuty // 83 .word nadSetChannelSource // 84 .word nadSetChannelSourcePSG // 85 .word nadSetChannelSourceNoise // 86 .word nadSetChannelTimer // 87 .word nadStartChannels // 88 .word nadStopChannels // 89 .word nadWriteSOUNDCNT // 8A .word nadWriteSOUNDBIAS // 8B .word nadWriteCaptureControl // 8C .word nadWriteCaptureDest // 8D .word nadWriteCaptureLength // 8E .word nadWriteCaptureControl2 // 8F /****************************************************************************** * void nasProcessFifo() * * process fifo messages ******************************************************************************/ public function nasProcessFifo //----------------------------------------------------------------------------- push {r4-r7, lr} //----------------------------------------------------------------------------- bl naSuspendIRQ_t //; irqsafe: ldr r4,=fifoPosition //; r5 = read position ldr r5, [r4, #0] //; r6 = write position ldr r6, [r4, #4] //; read = write str r6, [r4, #0] // bl naRestoreIRQ_t // //----------------------------------------------------------------------------- cmp r5, r6 beq .nomessages ldr r4,=fifo ldr r7,=messageReturn //----------------------------------------------------------------------------- _loop1: bl fifoPull lsl r1, r0, #32-6 //; mask 6bit message index lsr r1, #32-6-2 //; *4 for memory pointer adr r2, messageTable ldr r2, [r2, r1] bx r2 //----------------------------------------------------------------------------- function messageReturn ldr r0,=naSharedData9 ldr r0, [r0] ldr r1, [r0, #SD9_MSGCOUNTER] add r1, #1 str r1, [r0, #SD9_MSGCOUNTER] cmp r5, r6 bne _loop1 .nomessages: pop {r4-r7} pop {r0} bx r0 .align messageTable: .word messageInit .word messageReset .word messageProgram .word messageOpenTrack .word messageCloseTrack .word messageLock .word messageUnlock .word messageSequencer .word messageUnprogram .word messageSrExt .word messageStopSource .word messageGetLevels .word messageRampSpeed /****************************************************************************** * u32 fifoPull() * * read word from fifo & increment pointer * * * r4 = fifo pointer * r5 = read position ******************************************************************************/ function fifoPull //----------------------------------------------------------------------------- ldr r0, [r4, r5] add r5, #4 lsl r5, #32-FIFO_SHIFT lsr r5, #32-FIFO_SHIFT bx lr /****************************************************************************** * messageInit() * * initialize system ******************************************************************************/ function messageInit bl fifoPull bl naInit bx r7 /****************************************************************************** * messageReset * * reset audio * * d7-d15 = new mode ******************************************************************************/ function messageReset lsr r0, #8 bl naReset bx r7 /****************************************************************************** * messageProgram * * program sequencer * * word1 = ext data ptr ******************************************************************************/ function messageProgram bl fifoPull bl nasAddProgram bx r7 /****************************************************************************** * messageUnprogram * * reset sequencer programming ******************************************************************************/ function messageUnprogram bx r7 /****************************************************************************** * messageOpenTrack * * open sequencer track ******************************************************************************/ function messageOpenTrack //----------------------------------------------------------------------------- push {r0} //; push data onto stack bl fifoPull //; push {r0} //; bl fifoPull //; push {r0} //; //----------------------------------------------------------------------------- mov r0, sp //; open track bl nasOpenTrack //; //----------------------------------------------------------------------------- add sp, #12 //; restore sp bx r7 /****************************************************************************** * messageCloseTrack * * close sequencer track * * d7-d15 = track handle ******************************************************************************/ function messageCloseTrack lsr r0, #8 bl nasCloseTrack bx r7 /****************************************************************************** * messageLock * * lock audio channels * * word1: channel bitmask ******************************************************************************/ function messageLock bl fifoPull bl naLockVoices bx r7 /****************************************************************************** * messageUnlock * * unlock audio channels * * word1: channel bitmask ******************************************************************************/ function messageUnlock bl fifoPull bl naUnlockVoices bx r7 /****************************************************************************** * messageSequencer * * queue sequencer block * * word1: address of block ******************************************************************************/ function messageSequencer bl fifoPull bl nasNewBlock bx r7 /******************************************************************************* * messageSrExt * * register track extension * * todo: describe data formatting *******************************************************************************/ function messageSrExt mov r1, #255 // r0,r1,r2 = track,slot,ext mov r2, #255 // lsr r0, #8 // and r2, r0 // lsr r0, #8 // and r1, r0 // lsr r0, #8 // bl nasSetExtension // bx r7 // function messageStopSource lsr r0, #8 push {r0} bl fifoPull pop {r1} bl naStopSource bx r7 function messageGetLevels ldr r0,=naUpdateLevelsFlag mov r1, #1 strb r1, [r0] bx r7 function messageRampSpeed bl fifoPull bl naxSetRampingSpeed bx r7 @------------------------------------------------------------------------------- public function nafSendMsg1 @------------------------------------------------------------------------------- mov r3, #4 .sendmsg: push {r0-r2,lr} mov r0, #FIFO_CHANNEL mov r1, r3 mov r2, sp bl fifoSendDatamsg pop {r0-r2} pop {r0} bx r0 @------------------------------------------------------------------------------- public function nafSendMsg2 @------------------------------------------------------------------------------- mov r3, #8 b .sendmsg @------------------------------------------------------------------------------- public function nafSendMsg3 @------------------------------------------------------------------------------- mov r3, #12 b .sendmsg