2 * $Id: aica.c,v 1.24 2007-10-24 21:24:09 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
23 #include "dreamcast.h"
25 #include "aica/aica.h"
27 #include "aica/audio.h"
31 MMIO_REGION_READ_DEFFN( AICA0 )
32 MMIO_REGION_READ_DEFFN( AICA1 )
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 };
46 /* 20 years in seconds */
47 #define RTC_OFFSET 631152000
48 unsigned int aica_time_of_day = 0;
51 * Initialize the AICA subsystem. Note requires that
53 void aica_init( void )
55 register_io_regions( mmio_list_spu );
62 void aica_reset( void )
65 aica_event(2); /* Pre-deliver a timer interrupt */
66 aica_time_of_day = 0x5bfc8900;
69 void aica_start( void )
75 * Keep track of what we've done so far this second, to try to keep the
76 * precision of samples/second.
79 uint32_t nanosecs_done = 0;
81 uint32_t aica_run_slice( uint32_t nanosecs )
83 /* Run arm instructions */
84 int reset = MMIO_READ( AICA2, AICA_RESET );
85 if( (reset & 1) == 0 ) { /* Running */
86 int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (nanosecs_done + nanosecs) / 1000000000) - samples_done;
87 num_samples = arm_run_slice( num_samples );
88 audio_mix_samples( num_samples );
90 samples_done += num_samples;
91 nanosecs_done += nanosecs;
93 if( nanosecs_done > 1000000000 ) {
94 samples_done -= AICA_SAMPLE_RATE;
95 nanosecs_done -= 1000000000;
101 void aica_stop( void )
106 void aica_save_state( FILE *f )
111 int aica_load_state( FILE *f )
113 return arm_load_state( f );
116 int aica_event_pending = 0;
117 int aica_clear_count = 0;
119 /* Note: This is probably not necessarily technically correct but it should
120 * work in the meantime.
123 void aica_event( int event )
125 if( aica_event_pending == 0 )
126 armr.int_pending |= CPSR_F;
127 aica_event_pending |= (1<<event);
129 int pending = MMIO_READ( AICA2, AICA_IRQ );
130 if( pending == 0 || event < pending )
131 MMIO_WRITE( AICA2, AICA_IRQ, event );
134 void aica_clear_event( )
137 if( aica_clear_count == 4 ) {
139 aica_clear_count = 0;
141 for( i=0; i<8; i++ ) {
142 if( aica_event_pending & (1<<i) ) {
143 aica_event_pending &= ~(1<<i);
148 if( aica_event_pending & (1<<i) ) {
149 MMIO_WRITE( AICA2, AICA_IRQ, i );
153 if( aica_event_pending == 0 )
154 armr.int_pending &= ~CPSR_F;
158 void aica_enable( void )
160 mmio_region_AICA2_write( AICA_RESET, MMIO_READ(AICA2,AICA_RESET) & ~1 );
163 /** Channel register structure:
164 * 00 4 Channel config
165 * 04 4 Waveform address lo (16 bits)
166 * 08 4 Loop start address
167 * 0C 4 Loop end address
168 * 10 4 Volume envelope
170 * 18 4 Frequency (floating point)
183 /* Write to channels 0-31 */
184 void mmio_region_AICA0_write( uint32_t reg, uint32_t val )
186 MMIO_WRITE( AICA0, reg, val );
187 aica_write_channel( reg >> 7, reg % 128, val );
188 // DEBUG( "AICA0 Write %08X => %08X", val, reg );
191 /* Write to channels 32-64 */
192 void mmio_region_AICA1_write( uint32_t reg, uint32_t val )
194 MMIO_WRITE( AICA1, reg, val );
195 aica_write_channel( (reg >> 7) + 32, reg % 128, val );
196 // DEBUG( "AICA1 Write %08X => %08X", val, reg );
200 * AICA control registers
202 void mmio_region_AICA2_write( uint32_t reg, uint32_t val )
207 tmp = MMIO_READ( AICA2, AICA_RESET );
208 if( (tmp & 1) == 1 && (val & 1) == 0 ) {
209 /* ARM enabled - execute a core reset */
210 DEBUG( "ARM enabled" );
214 } else if( (tmp&1) == 0 && (val&1) == 1 ) {
215 DEBUG( "ARM disabled" );
217 MMIO_WRITE( AICA2, AICA_RESET, val );
223 MMIO_WRITE( AICA2, reg, val );
228 int32_t mmio_region_AICA2_read( uint32_t reg )
230 audio_channel_t channel;
235 channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
236 channel = audio_get_channel(channo);
237 if( channel->loop == LOOP_LOOPED ) {
239 channel->loop = LOOP_ON;
245 channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
246 channel = audio_get_channel(channo);
247 return channel->posn;
249 return MMIO_READ( AICA2, reg );
253 int32_t mmio_region_AICARTC_read( uint32_t reg )
258 rv = (aica_time_of_day >> 16) & 0xFFFF;
261 rv = aica_time_of_day & 0xFFFF;
264 // DEBUG( "Read AICA RTC %d => %08X", reg, rv );
269 void mmio_region_AICARTC_write( uint32_t reg, uint32_t val )
273 MMIO_WRITE( AICARTC, reg, val&0x01 );
276 if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
277 aica_time_of_day = (aica_time_of_day & 0xFFFF0000) | (val & 0xFFFF);
281 if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
282 aica_time_of_day = (aica_time_of_day & 0xFFFF) | (val<<16);
283 MMIO_WRITE( AICARTC, AICA_RTCEN, 0 );
290 * Translate the channel frequency to a sample rate. The frequency is a
291 * 14-bit floating point number, where bits 0..9 is the mantissa,
292 * 11..14 is the signed exponent (-8 to +7). Bit 10 appears to
295 * @return sample rate in samples per second.
297 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
299 uint32_t exponent = (freq & 0x3800) >> 11;
300 uint32_t mantissa = freq & 0x03FF;
302 if( freq & 0x4000 ) {
303 /* neg exponent - rate < 44100 */
304 exponent = 8 - exponent;
305 rate = (44100 >> exponent) +
306 ((44100 * mantissa) >> (10+exponent));
308 /* pos exponent - rate > 44100 */
309 rate = (44100 << exponent) +
310 ((44100 * mantissa) >> (10-exponent));
315 void aica_start_stop_channels()
318 for( i=0; i<32; i++ ) {
319 uint32_t val = MMIO_READ( AICA0, i<<7 );
320 audio_start_stop_channel(i, val&0x4000);
323 uint32_t val = MMIO_READ( AICA1, (i-32)<<7 );
324 audio_start_stop_channel(i, val&0x4000);
329 * Derived directly from Dan Potter's log table
331 uint8_t aica_volume_table[256] = {
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
333 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
334 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
335 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
336 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
337 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
338 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
339 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
340 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
341 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
342 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
343 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
344 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
345 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
346 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
347 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
350 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val )
353 audio_channel_t channel = audio_get_channel(channelNo);
355 case 0x00: /* Config + high address bits*/
356 channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
358 channel->loop = LOOP_ON;
360 channel->loop = LOOP_OFF;
361 switch( (val >> 7) & 0x03 ) {
363 channel->sample_format = AUDIO_FMT_16BIT;
366 channel->sample_format = AUDIO_FMT_8BIT;
370 channel->sample_format = AUDIO_FMT_ADPCM;
374 aica_start_stop_channels();
377 case 0x04: /* Low 16 address bits */
378 channel->start = (channel->start & 0x001F0000) | val;
380 case 0x08: /* Loop start */
381 channel->loop_start = val;
386 case 0x10: /* Envelope register 1 */
388 case 0x14: /* Envelope register 2 */
390 case 0x18: /* Frequency */
391 channel->sample_rate = aica_frequency_to_sample_rate ( val );
395 case 0x24: /* Volume? /pan */
398 val = 0x0F - val; /* Convert to smooth pan over 0..31 */
401 case 0x28: /* Volume */
402 channel->vol = aica_volume_table[val & 0xFF];
.