2 * $Id: aica.c,v 1.16 2006-01-22 22:40:05 nkeynes Exp $
4 * This is the core sound system (ie the bit which does the actual work)
6 * Copyright (c) 2005 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #define MODULE aica_module
22 #include "dreamcast.h"
30 MMIO_REGION_READ_DEFFN( AICA0 )
31 MMIO_REGION_READ_DEFFN( AICA1 )
32 MMIO_REGION_READ_DEFFN( AICA2 )
34 void aica_init( void );
35 void aica_reset( void );
36 void aica_start( void );
37 void aica_stop( void );
38 void aica_save_state( FILE *f );
39 int aica_load_state( FILE *f );
40 uint32_t aica_run_slice( uint32_t );
42 struct dreamcast_module aica_module = { "AICA", aica_init, aica_reset,
43 aica_start, aica_run_slice, aica_stop,
44 aica_save_state, aica_load_state };
47 * Initialize the AICA subsystem. Note requires that
49 void aica_init( void )
51 register_io_regions( mmio_list_spu );
56 audio_set_output( &esd_audio_driver, 44100, AUDIO_FMT_16BIT|AUDIO_FMT_STEREO );
59 void aica_reset( void )
62 aica_event(2); /* Pre-deliver a timer interrupt */
65 void aica_start( void )
71 * Keep track of what we've done so far this second, to try to keep the
72 * precision of samples/second.
75 uint32_t nanosecs_done = 0;
77 uint32_t aica_run_slice( uint32_t nanosecs )
79 /* Run arm instructions */
80 int reset = MMIO_READ( AICA2, AICA_RESET );
81 if( (reset & 1) == 0 ) { /* Running */
82 int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (nanosecs_done + nanosecs) / 1000000000) - samples_done;
83 num_samples = arm_run_slice( num_samples );
84 audio_mix_samples( num_samples );
86 samples_done += num_samples;
87 nanosecs_done += nanosecs;
89 if( nanosecs_done > 1000000000 ) {
90 samples_done -= AICA_SAMPLE_RATE;
91 nanosecs_done -= 1000000000;
96 void aica_stop( void )
101 void aica_save_state( FILE *f )
106 int aica_load_state( FILE *f )
108 return arm_load_state( f );
111 int aica_event_pending = 0;
112 int aica_clear_count = 0;
114 /* Note: This is probably not necessarily technically correct but it should
115 * work in the meantime.
118 void aica_event( int event )
120 if( aica_event_pending == 0 )
121 armr.int_pending |= CPSR_F;
122 aica_event_pending |= (1<<event);
124 int pending = MMIO_READ( AICA2, AICA_IRQ );
125 if( pending == 0 || event < pending )
126 MMIO_WRITE( AICA2, AICA_IRQ, event );
129 void aica_clear_event( )
132 if( aica_clear_count == 4 ) {
134 aica_clear_count = 0;
136 for( i=0; i<8; i++ ) {
137 if( aica_event_pending & (1<<i) ) {
138 aica_event_pending &= ~(1<<i);
143 if( aica_event_pending & (1<<i) ) {
144 MMIO_WRITE( AICA2, AICA_IRQ, i );
148 if( aica_event_pending == 0 )
149 armr.int_pending &= ~CPSR_F;
153 void aica_enable( void )
155 mmio_region_AICA2_write( AICA_RESET, MMIO_READ(AICA2,AICA_RESET) & ~1 );
158 /** Channel register structure:
159 * 00 4 Channel config
160 * 04 4 Waveform address lo (16 bits)
161 * 08 4 Loop start address
162 * 0C 4 Loop end address
163 * 10 4 Volume envelope
165 * 18 4 Frequency (floating point)
178 /* Write to channels 0-31 */
179 void mmio_region_AICA0_write( uint32_t reg, uint32_t val )
181 MMIO_WRITE( AICA0, reg, val );
182 aica_write_channel( reg >> 7, reg % 128, val );
183 // DEBUG( "AICA0 Write %08X => %08X", val, reg );
186 /* Write to channels 32-64 */
187 void mmio_region_AICA1_write( uint32_t reg, uint32_t val )
189 MMIO_WRITE( AICA1, reg, val );
190 aica_write_channel( (reg >> 7) + 32, reg % 128, val );
191 // DEBUG( "AICA1 Write %08X => %08X", val, reg );
195 * AICA control registers
197 void mmio_region_AICA2_write( uint32_t reg, uint32_t val )
202 tmp = MMIO_READ( AICA2, AICA_RESET );
203 if( (tmp & 1) == 1 && (val & 1) == 0 ) {
204 /* ARM enabled - execute a core reset */
205 DEBUG( "ARM enabled" );
209 } else if( (tmp&1) == 0 && (val&1) == 1 ) {
210 DEBUG( "ARM disabled" );
212 MMIO_WRITE( AICA2, AICA_RESET, val );
218 MMIO_WRITE( AICA2, reg, val );
224 * Translate the channel frequency to a sample rate. The frequency is a
225 * 14-bit floating point number, where bits 0..9 is the mantissa,
226 * 11..14 is the signed exponent (-8 to +7). Bit 10 appears to
229 * @return sample rate in samples per second.
231 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
233 uint32_t exponent = (freq & 0x3800) >> 11;
234 uint32_t mantissa = freq & 0x03FF;
236 if( freq & 0x4000 ) {
237 /* neg exponent - rate < 44100 */
238 exponent = 8 - exponent;
239 rate = (44100 >> exponent) +
240 ((44100 * mantissa) >> (10+exponent));
242 /* pos exponent - rate > 44100 */
243 rate = (44100 << exponent) +
244 ((44100 * mantissa) >> (10-exponent));
250 * Derived directly from Dan Potter's log table
252 uint8_t aica_volume_table[256] = {
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
254 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
255 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
256 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
257 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
258 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
259 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
260 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
261 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
262 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
263 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
264 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
265 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
266 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
267 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
268 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
271 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val )
274 audio_channel_t channel = audio_get_channel(channelNo);
276 case 0x00: /* Config + high address bits*/
277 channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
279 channel->loop = TRUE;
281 channel->loop = FALSE;
282 switch( (val >> 7) & 0x03 ) {
284 channel->sample_format = AUDIO_FMT_16BIT;
287 channel->sample_format = AUDIO_FMT_8BIT;
291 channel->sample_format = AUDIO_FMT_ADPCM;
294 switch( (val >> 14) & 0x03 ) {
296 audio_stop_channel( channelNo );
299 audio_start_channel( channelNo );
306 case 0x04: /* Low 16 address bits */
307 channel->start = (channel->start & 0x001F0000) | val;
309 case 0x08: /* Loop start */
310 channel->loop_start = val;
315 case 0x10: /* Envelope register 1 */
317 case 0x14: /* Envelope register 2 */
319 case 0x18: /* Frequency */
320 channel->sample_rate = aica_frequency_to_sample_rate ( val );
324 case 0x24: /* Volume? /pan */
327 val = 0x0F - val; /* Convert to smooth pan over 0..31 */
330 case 0x28: /* Volume */
331 channel->vol = aica_volume_table[val & 0xFF];
.