After having performed various tests on real hardware I found out that the direct audio channels behave slightly different from what is generally believed. (I hope I didn't forget anything)
The fifo's of the two channels work as follows:
They are made from a 7 (!) 32-bit word ring buffer
Internally there's a separate 32-bit word for each of the two channels that is used as the current playing buffer
When the timer overflows:
(1) if there are 4 or more empty words in the fifo, then a dma request is issued
(2) if the current playing buffer is empty, and the fifo has at least one word available, it is transferred to the buffer. Note that this means that two dma requests will never happen without an extra timer overflow in-between, since there is simply no place in the buffer yet! If both the fifo and the current playing word are empty, I guess it will keep playing the last played sample. It definitely won't loop on the current play buffer, so I suppose the samples are shifted out of there or so.
Writing to the fifo using the cpu will always perform a modification on the 32 bit word in the fifo that is currently to be written and then move the write pointer to the next word. 32 bit writes obviously work as expected and write 4 new samples. On 16 and 8 bit writes, it will also result in 4 new samples, but 2 respectively 3 samples will be left over from the old value on that place in the ring buffer. Which depends on what part of the fifo register you write.
For example say that the current fifo write location contained 0xAABBCCDD previously and you do *(vu8*)0x040000A0 = 8;. This results in the value 0xAABBCC08 to be written to the fifo. Similarly if you write to other parts, only the addressed part will be replaced. So *(vu8*)0x040000A3 = 2; results in 0x02BBCCDD. This works similar for 16 bit, but then either the upper or lower 16 bits will be replaced.
It seems that when the fifo overflows, it is reset to an empty state (similar to writing the fifo reset bit in SOUNDCNT_H).
Sound fifo dma is forced to 32 bit, but the destination address is not forced to be the sound fifo. As such it is possible to generate interrupts whenever there is enough space for 16 samples in the fifo by setting the destination to 0x00000000 or something and doing cpu writes in the dma interrupt.
This test rom will help checking if the dma request timings are correct. directaudiotest.zip
Expected output is as follows (ran on a dslite in gba mode):
The numbers are the number of cycles between iterations of the loop in this function:
The text was updated successfully, but these errors were encountered: