# Audio Controller The audio controller provides four channels of 16-bit PCM audio playback. It uses multiple registers starting at address $A00. Each of the four channels has three registers. For the first channel the register addresses are: |Address|Description| |-------|-----------| | $A00 | Control Register | | $A01 | Clock Divider Register | | $A02 | Amplitude Register | The register addresses for the second channel start at $A04, the third channel at $A08 and the fourth channel at $A0C. ## Reading the control register |_bit_ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | |_Value_|- |- |- |- |- |- |- |- |- |-|- |- |- |- |- |- | |_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | |_Value_|- |- |- |- |- |- |- |- |- |- |- |i |f | e | p | c | |Bitfields|Description| |---------|-----------| | _i_ | interrupt is enabled for this channel when 1 | | _f_ | sample buffer is full when 1 | | _e_ | sample buffer is empty when 1 | | _p_ | changes from 0 to 1 and vice versa on each sample clock | | _c_ | channel is enabled if 1 | ## Writing the control register |_bit_ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | |_Value_|- |- |- |- |- |- |- |- |- |-|- |- |- |- |- |- | |_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | |_Value_|- |- |- |- |- |- |- |- |- |- |- |i |- | - | - | c | |Bitfields|Description| |---------|-----------| | _c_ | enable channel if 1, disable if 0 | | _i_ | enable channel interrupt if 1, disable if 0 | ## Writing the clock divider register |_bit_ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | |_Value_|d |d |d |d |d |d |d |d |d |d|d |d |d |d |d |d | |_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | |_Value_|d |d |d |d |d |d |d |d |d |d|d |d |d |d |d |d | |Bitfields|Description| |---------|-----------| | _d_ | an unsigned 32-bit value for the clock divider | ## Writing the amplitude register |_bit_ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | |_Value_|- |- |- |- |- |- |- |- |- |-|- |- |- |- |- |- | |_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | |_Value_|a |a |a |a |a |a |a |a |a |a |a |a |a | a | a | a | |Bitfields|Description| |---------|-----------| | _a_ | an unsigned 16-bit value for the amplitude (sample) value with a bias of 32768 | ## Notes The clock divider specifies the number of CPU clock ticks between two samples. Writing to the amplitude register adds the sample value to the sample buffer. The sample buffer is organized as a FIFO with 16 elements. Amplitude (sample) values are represented as unsigned, biased 16-bit numbers. The bias is 32768, so given an amplitude range of 1.0 to -1.0, a 1.0 is represented by 65535, 0.0 by 32768 and -1.0 by 0. Interrupt processing needs to be enabled for each channel if required. An interrupt on any channel will be signalled to the interrupt controller as IRQ 2. The interrupt service routine should check all running channels for an emtpy buffer. If an audio interrupt has occured on a channel, the interrupt enable flag is cleared for that channel. It needs to be re-enabled in the interrupt service routine. Interrupts also need to be enabled on the interrupt controller, and re-enabled there after each interrupt.