AI Registers Detailed
Jump to navigation
Jump to search
Taken from Lac's hw-dox.
Trainer examples
heres how one way to make sound on N64 :
Crazy nation trainer (xtremeG version)
[we tested button and its time to make sound!]
lui $t4,8031 ;make pointer to 'yes' sound
addiu $t4,$t4,4F10 ;80314f10 = start
addiu $t5,$zero,4A71 ;4A71=length
addiu $t6,$zero,1388 ;1388= DAC rate
addiu $t7,$zero,0001 ;1=BIT rate
jal here
nop
[draw yes]
......
[we tested button and time to make 'no' sound]
lui $t4,8031 ;make pointer to 'no' sound
addiu $t4,$t4,12C4 ;803112C4
addiu $t5,$zero,3C45 ;3C45=length
addiu $t6,$zero,1388 ;DAC rate
addiu $t7,$zero,0001 ;1=BIT rate
jal here
nop
[draw no]
.....
[...initialize vid, audio]
addiu $t4,$zero,0000 ;[blank out sound]
addiu $t5,$zero,0000 ;initialize
addiu $t6,$zero,0001
addiu $t7,$zero,0001
here: lui $t8,A450
sw $t4,0000($t8) ;start RDRAM address
sw $t5,0004($t8) ;length
addiu $t9,$zero,0001
sw $t9,0008($t8) ;1 = enable dma
sw $t6,0010($t8) ;dac rate
sw $t7,0014($t8) ;bit rate
jr $ra
nop
Initialization
None needed. Although, I suppose you can include setting the sound frequency and/or enabling the AI_CONTROL_REG as initialization (step #4 below)
Setting Frequency
1. Set the dac rate
write to AI_DACRATE_REG this value: (VI_NTSC_CLOCK/freq)-1
^could be pal
2. Set the bitrate (4bit, 8bit, or 16bit)
write to the AI_BITRATE_REG the value: bitrate-1
Sending Sound Buffer
1. Before sending a buffer, its a good idea to make sure one isnt already
being played. Simply read AI_STATUS_REG then AND it with
AI_STATUS_FIFO_FULL. if the result is true... then wait.
2. Write the 64bit aligned address of the sound buffer to AI_DRAM_ADDR_REG
3. Write the length of the buffer be played to AI_LEN_REG
NOTE: this length must be multiple of 8, no larger than 262144 bytes.
4. Write AI_CONTROL_DMA_ON to the AI_CONTROL_REG (only needed once)
* end sound buffer
NOTE: If you have read the libultra manuals you will notice when it discusses the AI routines (osAi.man) it says the AI regs are double buffered.
This is important to realize that you can send one buffer while another is playing. Also note that the AI_LEN_REG counts down to 0 as the current buffer
is being played. This can be useful to tell how much of the buffer is left.