2 * $Id: aica.c,v 1.19 2006-06-27 11:04:03 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 )
67 aica_event(2); /* Pre-deliver a timer interrupt */
69 // gettimeofday( &tv, NULL );
70 // aica_time_of_day = tv.tv_sec + RTC_OFFSET;
71 aica_time_of_day = 0x5bfc8900;
74 void aica_start( void )
80 * Keep track of what we've done so far this second, to try to keep the
81 * precision of samples/second.
84 uint32_t nanosecs_done = 0;
86 uint32_t aica_run_slice( uint32_t nanosecs )
88 /* Run arm instructions */
89 int reset = MMIO_READ( AICA2, AICA_RESET );
90 if( (reset & 1) == 0 ) { /* Running */
91 int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (nanosecs_done + nanosecs) / 1000000000) - samples_done;
92 num_samples = arm_run_slice( num_samples );
93 audio_mix_samples( num_samples );
95 samples_done += num_samples;
96 nanosecs_done += nanosecs;
98 if( nanosecs_done > 1000000000 ) {
99 samples_done -= AICA_SAMPLE_RATE;
100 nanosecs_done -= 1000000000;
106 void aica_stop( void )
111 void aica_save_state( FILE *f )
116 int aica_load_state( FILE *f )
118 return arm_load_state( f );
121 int aica_event_pending = 0;
122 int aica_clear_count = 0;
124 /* Note: This is probably not necessarily technically correct but it should
125 * work in the meantime.
128 void aica_event( int event )
130 if( aica_event_pending == 0 )
131 armr.int_pending |= CPSR_F;
132 aica_event_pending |= (1<<event);
134 int pending = MMIO_READ( AICA2, AICA_IRQ );
135 if( pending == 0 || event < pending )
136 MMIO_WRITE( AICA2, AICA_IRQ, event );
139 void aica_clear_event( )
142 if( aica_clear_count == 4 ) {
144 aica_clear_count = 0;
146 for( i=0; i<8; i++ ) {
147 if( aica_event_pending & (1<<i) ) {
148 aica_event_pending &= ~(1<<i);
153 if( aica_event_pending & (1<<i) ) {
154 MMIO_WRITE( AICA2, AICA_IRQ, i );
158 if( aica_event_pending == 0 )
159 armr.int_pending &= ~CPSR_F;
163 void aica_enable( void )
165 mmio_region_AICA2_write( AICA_RESET, MMIO_READ(AICA2,AICA_RESET) & ~1 );
168 /** Channel register structure:
169 * 00 4 Channel config
170 * 04 4 Waveform address lo (16 bits)
171 * 08 4 Loop start address
172 * 0C 4 Loop end address
173 * 10 4 Volume envelope
175 * 18 4 Frequency (floating point)
188 /* Write to channels 0-31 */
189 void mmio_region_AICA0_write( uint32_t reg, uint32_t val )
191 MMIO_WRITE( AICA0, reg, val );
192 aica_write_channel( reg >> 7, reg % 128, val );
193 // DEBUG( "AICA0 Write %08X => %08X", val, reg );
196 /* Write to channels 32-64 */
197 void mmio_region_AICA1_write( uint32_t reg, uint32_t val )
199 MMIO_WRITE( AICA1, reg, val );
200 aica_write_channel( (reg >> 7) + 32, reg % 128, val );
201 // DEBUG( "AICA1 Write %08X => %08X", val, reg );
205 * AICA control registers
207 void mmio_region_AICA2_write( uint32_t reg, uint32_t val )
212 tmp = MMIO_READ( AICA2, AICA_RESET );
213 if( (tmp & 1) == 1 && (val & 1) == 0 ) {
214 /* ARM enabled - execute a core reset */
215 DEBUG( "ARM enabled" );
219 } else if( (tmp&1) == 0 && (val&1) == 1 ) {
220 DEBUG( "ARM disabled" );
222 MMIO_WRITE( AICA2, AICA_RESET, val );
228 MMIO_WRITE( AICA2, reg, val );
234 int32_t mmio_region_AICARTC_read( uint32_t reg )
240 rv = (aica_time_of_day >> 16) & 0xFFFF;
243 rv = aica_time_of_day & 0xFFFF;
246 DEBUG( "Read AICA RTC %d => %08X", reg, rv );
250 MMIO_REGION_WRITE_STUBFN( AICARTC )
253 * Translate the channel frequency to a sample rate. The frequency is a
254 * 14-bit floating point number, where bits 0..9 is the mantissa,
255 * 11..14 is the signed exponent (-8 to +7). Bit 10 appears to
258 * @return sample rate in samples per second.
260 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
262 uint32_t exponent = (freq & 0x3800) >> 11;
263 uint32_t mantissa = freq & 0x03FF;
265 if( freq & 0x4000 ) {
266 /* neg exponent - rate < 44100 */
267 exponent = 8 - exponent;
268 rate = (44100 >> exponent) +
269 ((44100 * mantissa) >> (10+exponent));
271 /* pos exponent - rate > 44100 */
272 rate = (44100 << exponent) +
273 ((44100 * mantissa) >> (10-exponent));
279 * Derived directly from Dan Potter's log table
281 uint8_t aica_volume_table[256] = {
282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
283 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
284 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
285 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
286 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
287 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
288 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
289 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
290 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
291 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
292 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
293 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
294 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
295 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
296 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
297 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
300 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val )
303 audio_channel_t channel = audio_get_channel(channelNo);
305 case 0x00: /* Config + high address bits*/
306 channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
308 channel->loop = TRUE;
310 channel->loop = FALSE;
311 switch( (val >> 7) & 0x03 ) {
313 channel->sample_format = AUDIO_FMT_16BIT;
316 channel->sample_format = AUDIO_FMT_8BIT;
320 channel->sample_format = AUDIO_FMT_ADPCM;
323 switch( (val >> 14) & 0x03 ) {
325 audio_stop_channel( channelNo );
328 audio_start_channel( channelNo );
335 case 0x04: /* Low 16 address bits */
336 channel->start = (channel->start & 0x001F0000) | val;
338 case 0x08: /* Loop start */
339 channel->loop_start = val;
344 case 0x10: /* Envelope register 1 */
346 case 0x14: /* Envelope register 2 */
348 case 0x18: /* Frequency */
349 channel->sample_rate = aica_frequency_to_sample_rate ( val );
353 case 0x24: /* Volume? /pan */
356 val = 0x0F - val; /* Convert to smooth pan over 0..31 */
359 case 0x28: /* Volume */
360 channel->vol = aica_volume_table[val & 0xFF];
.