2 * $Id: aica.c,v 1.23 2007-10-09 11:37:36 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 )
33 MMIO_REGION_READ_DEFFN( AICA2 )
35 void aica_init( void );
36 void aica_reset( void );
37 void aica_start( void );
38 void aica_stop( void );
39 void aica_save_state( FILE *f );
40 int aica_load_state( FILE *f );
41 uint32_t aica_run_slice( uint32_t );
43 struct dreamcast_module aica_module = { "AICA", aica_init, aica_reset,
44 aica_start, aica_run_slice, aica_stop,
45 aica_save_state, aica_load_state };
47 /* 20 years in seconds */
48 #define RTC_OFFSET 631152000
49 unsigned int aica_time_of_day = 0;
52 * Initialize the AICA subsystem. Note requires that
54 void aica_init( void )
56 register_io_regions( mmio_list_spu );
63 void aica_reset( void )
66 aica_event(2); /* Pre-deliver a timer interrupt */
67 aica_time_of_day = 0x5bfc8900;
70 void aica_start( void )
76 * Keep track of what we've done so far this second, to try to keep the
77 * precision of samples/second.
80 uint32_t nanosecs_done = 0;
82 uint32_t aica_run_slice( uint32_t nanosecs )
84 /* Run arm instructions */
85 int reset = MMIO_READ( AICA2, AICA_RESET );
86 if( (reset & 1) == 0 ) { /* Running */
87 int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (nanosecs_done + nanosecs) / 1000000000) - samples_done;
88 num_samples = arm_run_slice( num_samples );
89 audio_mix_samples( num_samples );
91 samples_done += num_samples;
92 nanosecs_done += nanosecs;
94 if( nanosecs_done > 1000000000 ) {
95 samples_done -= AICA_SAMPLE_RATE;
96 nanosecs_done -= 1000000000;
102 void aica_stop( void )
107 void aica_save_state( FILE *f )
112 int aica_load_state( FILE *f )
114 return arm_load_state( f );
117 int aica_event_pending = 0;
118 int aica_clear_count = 0;
120 /* Note: This is probably not necessarily technically correct but it should
121 * work in the meantime.
124 void aica_event( int event )
126 if( aica_event_pending == 0 )
127 armr.int_pending |= CPSR_F;
128 aica_event_pending |= (1<<event);
130 int pending = MMIO_READ( AICA2, AICA_IRQ );
131 if( pending == 0 || event < pending )
132 MMIO_WRITE( AICA2, AICA_IRQ, event );
135 void aica_clear_event( )
138 if( aica_clear_count == 4 ) {
140 aica_clear_count = 0;
142 for( i=0; i<8; i++ ) {
143 if( aica_event_pending & (1<<i) ) {
144 aica_event_pending &= ~(1<<i);
149 if( aica_event_pending & (1<<i) ) {
150 MMIO_WRITE( AICA2, AICA_IRQ, i );
154 if( aica_event_pending == 0 )
155 armr.int_pending &= ~CPSR_F;
159 void aica_enable( void )
161 mmio_region_AICA2_write( AICA_RESET, MMIO_READ(AICA2,AICA_RESET) & ~1 );
164 /** Channel register structure:
165 * 00 4 Channel config
166 * 04 4 Waveform address lo (16 bits)
167 * 08 4 Loop start address
168 * 0C 4 Loop end address
169 * 10 4 Volume envelope
171 * 18 4 Frequency (floating point)
184 /* Write to channels 0-31 */
185 void mmio_region_AICA0_write( uint32_t reg, uint32_t val )
187 MMIO_WRITE( AICA0, reg, val );
188 aica_write_channel( reg >> 7, reg % 128, val );
189 // DEBUG( "AICA0 Write %08X => %08X", val, reg );
192 /* Write to channels 32-64 */
193 void mmio_region_AICA1_write( uint32_t reg, uint32_t val )
195 MMIO_WRITE( AICA1, reg, val );
196 aica_write_channel( (reg >> 7) + 32, reg % 128, val );
197 // DEBUG( "AICA1 Write %08X => %08X", val, reg );
201 * AICA control registers
203 void mmio_region_AICA2_write( uint32_t reg, uint32_t val )
208 tmp = MMIO_READ( AICA2, AICA_RESET );
209 if( (tmp & 1) == 1 && (val & 1) == 0 ) {
210 /* ARM enabled - execute a core reset */
211 DEBUG( "ARM enabled" );
215 } else if( (tmp&1) == 0 && (val&1) == 1 ) {
216 DEBUG( "ARM disabled" );
218 MMIO_WRITE( AICA2, AICA_RESET, val );
224 MMIO_WRITE( AICA2, reg, val );
230 int32_t mmio_region_AICARTC_read( uint32_t reg )
235 rv = (aica_time_of_day >> 16) & 0xFFFF;
238 rv = aica_time_of_day & 0xFFFF;
241 // DEBUG( "Read AICA RTC %d => %08X", reg, rv );
246 void mmio_region_AICARTC_write( uint32_t reg, uint32_t val )
250 MMIO_WRITE( AICARTC, reg, val&0x01 );
253 if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
254 aica_time_of_day = (aica_time_of_day & 0xFFFF0000) | (val & 0xFFFF);
258 if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
259 aica_time_of_day = (aica_time_of_day & 0xFFFF) | (val<<16);
260 MMIO_WRITE( AICARTC, AICA_RTCEN, 0 );
267 * Translate the channel frequency to a sample rate. The frequency is a
268 * 14-bit floating point number, where bits 0..9 is the mantissa,
269 * 11..14 is the signed exponent (-8 to +7). Bit 10 appears to
272 * @return sample rate in samples per second.
274 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
276 uint32_t exponent = (freq & 0x3800) >> 11;
277 uint32_t mantissa = freq & 0x03FF;
279 if( freq & 0x4000 ) {
280 /* neg exponent - rate < 44100 */
281 exponent = 8 - exponent;
282 rate = (44100 >> exponent) +
283 ((44100 * mantissa) >> (10+exponent));
285 /* pos exponent - rate > 44100 */
286 rate = (44100 << exponent) +
287 ((44100 * mantissa) >> (10-exponent));
292 void aica_start_stop_channels()
295 for( i=0; i<32; i++ ) {
296 uint32_t val = MMIO_READ( AICA0, i<<7 );
297 audio_start_stop_channel(i, val&0x4000);
300 uint32_t val = MMIO_READ( AICA1, (i-32)<<7 );
301 audio_start_stop_channel(i, val&0x4000);
306 * Derived directly from Dan Potter's log table
308 uint8_t aica_volume_table[256] = {
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
310 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
311 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
312 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
313 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
314 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
315 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
316 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
317 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
318 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
319 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
320 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
321 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
322 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
323 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
324 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
327 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val )
330 audio_channel_t channel = audio_get_channel(channelNo);
332 case 0x00: /* Config + high address bits*/
333 channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
335 channel->loop = TRUE;
337 channel->loop = FALSE;
338 switch( (val >> 7) & 0x03 ) {
340 channel->sample_format = AUDIO_FMT_16BIT;
343 channel->sample_format = AUDIO_FMT_8BIT;
347 channel->sample_format = AUDIO_FMT_ADPCM;
351 aica_start_stop_channels();
354 case 0x04: /* Low 16 address bits */
355 channel->start = (channel->start & 0x001F0000) | val;
357 case 0x08: /* Loop start */
358 channel->loop_start = val;
363 case 0x10: /* Envelope register 1 */
365 case 0x14: /* Envelope register 2 */
367 case 0x18: /* Frequency */
368 channel->sample_rate = aica_frequency_to_sample_rate ( val );
372 case 0x24: /* Volume? /pan */
375 val = 0x0F - val; /* Convert to smooth pan over 0..31 */
378 case 0x28: /* Volume */
379 channel->vol = aica_volume_table[val & 0xFF];
.