2 * $Id: aica.c,v 1.18 2006-03-30 11:27:11 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 };
48 * Initialize the AICA subsystem. Note requires that
50 void aica_init( void )
52 register_io_regions( mmio_list_spu );
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 );
223 /* 20 years in seconds */
224 #define RTC_OFFSET 631152000
226 int32_t mmio_region_AICARTC_read( uint32_t reg )
232 if( gettimeofday( &tv, NULL ) == 0 ) {
233 return ((uint32_t)(tv.tv_sec + RTC_OFFSET)) >> 16;
237 if( gettimeofday( &tv, NULL ) == 0 ) {
238 return ((uint32_t)(tv.tv_sec + RTC_OFFSET)) & 0xFFFF;
245 MMIO_REGION_WRITE_STUBFN( AICARTC )
248 * Translate the channel frequency to a sample rate. The frequency is a
249 * 14-bit floating point number, where bits 0..9 is the mantissa,
250 * 11..14 is the signed exponent (-8 to +7). Bit 10 appears to
253 * @return sample rate in samples per second.
255 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
257 uint32_t exponent = (freq & 0x3800) >> 11;
258 uint32_t mantissa = freq & 0x03FF;
260 if( freq & 0x4000 ) {
261 /* neg exponent - rate < 44100 */
262 exponent = 8 - exponent;
263 rate = (44100 >> exponent) +
264 ((44100 * mantissa) >> (10+exponent));
266 /* pos exponent - rate > 44100 */
267 rate = (44100 << exponent) +
268 ((44100 * mantissa) >> (10-exponent));
274 * Derived directly from Dan Potter's log table
276 uint8_t aica_volume_table[256] = {
277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
278 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
279 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
280 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
281 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
282 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
283 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
284 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
285 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
286 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
287 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
288 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
289 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
290 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
291 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
292 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
295 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val )
298 audio_channel_t channel = audio_get_channel(channelNo);
300 case 0x00: /* Config + high address bits*/
301 channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
303 channel->loop = TRUE;
305 channel->loop = FALSE;
306 switch( (val >> 7) & 0x03 ) {
308 channel->sample_format = AUDIO_FMT_16BIT;
311 channel->sample_format = AUDIO_FMT_8BIT;
315 channel->sample_format = AUDIO_FMT_ADPCM;
318 switch( (val >> 14) & 0x03 ) {
320 audio_stop_channel( channelNo );
323 audio_start_channel( channelNo );
330 case 0x04: /* Low 16 address bits */
331 channel->start = (channel->start & 0x001F0000) | val;
333 case 0x08: /* Loop start */
334 channel->loop_start = val;
339 case 0x10: /* Envelope register 1 */
341 case 0x14: /* Envelope register 2 */
343 case 0x18: /* Frequency */
344 channel->sample_rate = aica_frequency_to_sample_rate ( val );
348 case 0x24: /* Volume? /pan */
351 val = 0x0F - val; /* Convert to smooth pan over 0..31 */
354 case 0x28: /* Volume */
355 channel->vol = aica_volume_table[val & 0xFF];
.