Search
lxdream.org :: lxdream/src/aica/aica.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/aica.c
changeset 736:a02d1475ccfd
prev642:c7383f21f122
next829:517425d04f1b
author nkeynes
date Tue Aug 19 22:58:05 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Add stubs for the (undocumented) SH4 performance counter registers
file annotate diff log raw
1.1 --- a/src/aica/aica.c Tue Feb 26 01:06:59 2008 +0000
1.2 +++ b/src/aica/aica.c Tue Aug 19 22:58:05 2008 +0000
1.3 @@ -41,8 +41,8 @@
1.4 uint32_t aica_run_slice( uint32_t );
1.5
1.6 struct dreamcast_module aica_module = { "AICA", aica_init, aica_reset,
1.7 - aica_start, aica_run_slice, aica_stop,
1.8 - aica_save_state, aica_load_state };
1.9 + aica_start, aica_run_slice, aica_stop,
1.10 + aica_save_state, aica_load_state };
1.11
1.12 struct aica_state_struct {
1.13 uint32_t time_of_day;
1.14 @@ -82,7 +82,7 @@
1.15 aica_state.nanosecs_done = 0;
1.16 aica_state.event_pending = 0;
1.17 aica_state.clear_count = 0;
1.18 -// aica_event(2); /* Pre-deliver a timer interrupt */
1.19 + // aica_event(2); /* Pre-deliver a timer interrupt */
1.20 }
1.21
1.22 void aica_start( void )
1.23 @@ -95,17 +95,17 @@
1.24 /* Run arm instructions */
1.25 int reset = MMIO_READ( AICA2, AICA_RESET );
1.26 if( (reset & 1) == 0 ) { /* Running */
1.27 - int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (aica_state.nanosecs_done + nanosecs) / 1000000000) - aica_state.samples_done;
1.28 - num_samples = arm_run_slice( num_samples );
1.29 - audio_mix_samples( num_samples );
1.30 + int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (aica_state.nanosecs_done + nanosecs) / 1000000000) - aica_state.samples_done;
1.31 + num_samples = arm_run_slice( num_samples );
1.32 + audio_mix_samples( num_samples );
1.33
1.34 - aica_state.samples_done += num_samples;
1.35 - aica_state.nanosecs_done += nanosecs;
1.36 + aica_state.samples_done += num_samples;
1.37 + aica_state.nanosecs_done += nanosecs;
1.38 }
1.39 if( aica_state.nanosecs_done > 1000000000 ) {
1.40 - aica_state.samples_done -= AICA_SAMPLE_RATE;
1.41 - aica_state.nanosecs_done -= 1000000000;
1.42 - aica_state.time_of_day++;
1.43 + aica_state.samples_done -= AICA_SAMPLE_RATE;
1.44 + aica_state.nanosecs_done -= 1000000000;
1.45 + aica_state.time_of_day++;
1.46 }
1.47 return nanosecs;
1.48 }
1.49 @@ -136,35 +136,35 @@
1.50 void aica_event( int event )
1.51 {
1.52 if( aica_state.event_pending == 0 )
1.53 - armr.int_pending |= CPSR_F;
1.54 + armr.int_pending |= CPSR_F;
1.55 aica_state.event_pending |= (1<<event);
1.56 -
1.57 +
1.58 int pending = MMIO_READ( AICA2, AICA_IRQ );
1.59 if( pending == 0 || event < pending )
1.60 - MMIO_WRITE( AICA2, AICA_IRQ, event );
1.61 + MMIO_WRITE( AICA2, AICA_IRQ, event );
1.62 }
1.63
1.64 void aica_clear_event( )
1.65 {
1.66 aica_state.clear_count++;
1.67 if( aica_state.clear_count == 4 ) {
1.68 - int i;
1.69 - aica_state.clear_count = 0;
1.70 + int i;
1.71 + aica_state.clear_count = 0;
1.72
1.73 - for( i=0; i<8; i++ ) {
1.74 - if( aica_state.event_pending & (1<<i) ) {
1.75 - aica_state.event_pending &= ~(1<<i);
1.76 - break;
1.77 - }
1.78 - }
1.79 - for( ;i<8; i++ ) {
1.80 - if( aica_state.event_pending & (1<<i) ) {
1.81 - MMIO_WRITE( AICA2, AICA_IRQ, i );
1.82 - break;
1.83 - }
1.84 - }
1.85 - if( aica_state.event_pending == 0 )
1.86 - armr.int_pending &= ~CPSR_F;
1.87 + for( i=0; i<8; i++ ) {
1.88 + if( aica_state.event_pending & (1<<i) ) {
1.89 + aica_state.event_pending &= ~(1<<i);
1.90 + break;
1.91 + }
1.92 + }
1.93 + for( ;i<8; i++ ) {
1.94 + if( aica_state.event_pending & (1<<i) ) {
1.95 + MMIO_WRITE( AICA2, AICA_IRQ, i );
1.96 + break;
1.97 + }
1.98 + }
1.99 + if( aica_state.event_pending == 0 )
1.100 + armr.int_pending &= ~CPSR_F;
1.101 }
1.102 }
1.103
1.104 @@ -218,24 +218,24 @@
1.105
1.106 switch( reg ) {
1.107 case AICA_RESET:
1.108 - tmp = MMIO_READ( AICA2, AICA_RESET );
1.109 - if( (tmp & 1) == 1 && (val & 1) == 0 ) {
1.110 - /* ARM enabled - execute a core reset */
1.111 - DEBUG( "ARM enabled" );
1.112 - arm_reset();
1.113 - aica_state.samples_done = 0;
1.114 - aica_state.nanosecs_done = 0;
1.115 - } else if( (tmp&1) == 0 && (val&1) == 1 ) {
1.116 - DEBUG( "ARM disabled" );
1.117 - }
1.118 - MMIO_WRITE( AICA2, AICA_RESET, val );
1.119 - break;
1.120 + tmp = MMIO_READ( AICA2, AICA_RESET );
1.121 + if( (tmp & 1) == 1 && (val & 1) == 0 ) {
1.122 + /* ARM enabled - execute a core reset */
1.123 + DEBUG( "ARM enabled" );
1.124 + arm_reset();
1.125 + aica_state.samples_done = 0;
1.126 + aica_state.nanosecs_done = 0;
1.127 + } else if( (tmp&1) == 0 && (val&1) == 1 ) {
1.128 + DEBUG( "ARM disabled" );
1.129 + }
1.130 + MMIO_WRITE( AICA2, AICA_RESET, val );
1.131 + break;
1.132 case AICA_IRQCLEAR:
1.133 - aica_clear_event();
1.134 - break;
1.135 + aica_clear_event();
1.136 + break;
1.137 default:
1.138 - MMIO_WRITE( AICA2, reg, val );
1.139 - break;
1.140 + MMIO_WRITE( AICA2, reg, val );
1.141 + break;
1.142 }
1.143 }
1.144
1.145 @@ -246,21 +246,21 @@
1.146 int32_t val;
1.147 switch( reg ) {
1.148 case AICA_CHANSTATE:
1.149 - channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
1.150 - channel = audio_get_channel(channo);
1.151 - if( channel->loop == LOOP_LOOPED ) {
1.152 - val = 0x8000;
1.153 - channel->loop = LOOP_ON;
1.154 - } else {
1.155 - val = 0;
1.156 - }
1.157 - return val;
1.158 + channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
1.159 + channel = audio_get_channel(channo);
1.160 + if( channel->loop == LOOP_LOOPED ) {
1.161 + val = 0x8000;
1.162 + channel->loop = LOOP_ON;
1.163 + } else {
1.164 + val = 0;
1.165 + }
1.166 + return val;
1.167 case AICA_CHANPOSN:
1.168 - channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
1.169 - channel = audio_get_channel(channo);
1.170 - return channel->posn;
1.171 + channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
1.172 + channel = audio_get_channel(channo);
1.173 + return channel->posn;
1.174 default:
1.175 - return MMIO_READ( AICA2, reg );
1.176 + return MMIO_READ( AICA2, reg );
1.177 }
1.178 }
1.179
1.180 @@ -270,10 +270,10 @@
1.181 switch( reg ) {
1.182 case AICA_RTCHI:
1.183 rv = (aica_state.time_of_day >> 16) & 0xFFFF;
1.184 - break;
1.185 + break;
1.186 case AICA_RTCLO:
1.187 - rv = aica_state.time_of_day & 0xFFFF;
1.188 - break;
1.189 + rv = aica_state.time_of_day & 0xFFFF;
1.190 + break;
1.191 }
1.192 // DEBUG( "Read AICA RTC %d => %08X", reg, rv );
1.193 return rv;
1.194 @@ -284,22 +284,22 @@
1.195 {
1.196 switch( reg ) {
1.197 case AICA_RTCEN:
1.198 - MMIO_WRITE( AICARTC, reg, val&0x01 );
1.199 - break;
1.200 + MMIO_WRITE( AICARTC, reg, val&0x01 );
1.201 + break;
1.202 case AICA_RTCLO:
1.203 - if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
1.204 - aica_state.time_of_day = (aica_state.time_of_day & 0xFFFF0000) | (val & 0xFFFF);
1.205 - }
1.206 - break;
1.207 + if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
1.208 + aica_state.time_of_day = (aica_state.time_of_day & 0xFFFF0000) | (val & 0xFFFF);
1.209 + }
1.210 + break;
1.211 case AICA_RTCHI:
1.212 - if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
1.213 - aica_state.time_of_day = (aica_state.time_of_day & 0xFFFF) | (val<<16);
1.214 - MMIO_WRITE( AICARTC, AICA_RTCEN, 0 );
1.215 - }
1.216 - break;
1.217 + if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
1.218 + aica_state.time_of_day = (aica_state.time_of_day & 0xFFFF) | (val<<16);
1.219 + MMIO_WRITE( AICARTC, AICA_RTCEN, 0 );
1.220 + }
1.221 + break;
1.222 }
1.223 }
1.224 -
1.225 +
1.226 /**
1.227 * Translate the channel frequency to a sample rate. The frequency is a
1.228 * 14-bit floating point number, where bits 0..9 is the mantissa,
1.229 @@ -314,14 +314,14 @@
1.230 uint32_t mantissa = freq & 0x03FF;
1.231 uint32_t rate;
1.232 if( freq & 0x4000 ) {
1.233 - /* neg exponent - rate < 44100 */
1.234 - exponent = 8 - exponent;
1.235 - rate = (44100 >> exponent) +
1.236 - ((44100 * mantissa) >> (10+exponent));
1.237 + /* neg exponent - rate < 44100 */
1.238 + exponent = 8 - exponent;
1.239 + rate = (44100 >> exponent) +
1.240 + ((44100 * mantissa) >> (10+exponent));
1.241 } else {
1.242 - /* pos exponent - rate > 44100 */
1.243 - rate = (44100 << exponent) +
1.244 - ((44100 * mantissa) >> (10-exponent));
1.245 + /* pos exponent - rate > 44100 */
1.246 + rate = (44100 << exponent) +
1.247 + ((44100 * mantissa) >> (10-exponent));
1.248 }
1.249 return rate;
1.250 }
1.251 @@ -330,12 +330,12 @@
1.252 {
1.253 int i;
1.254 for( i=0; i<32; i++ ) {
1.255 - uint32_t val = MMIO_READ( AICA0, i<<7 );
1.256 - audio_start_stop_channel(i, val&0x4000);
1.257 + uint32_t val = MMIO_READ( AICA0, i<<7 );
1.258 + audio_start_stop_channel(i, val&0x4000);
1.259 }
1.260 for( ; i<64; i++ ) {
1.261 - uint32_t val = MMIO_READ( AICA1, (i-32)<<7 );
1.262 - audio_start_stop_channel(i, val&0x4000);
1.263 + uint32_t val = MMIO_READ( AICA1, (i-32)<<7 );
1.264 + audio_start_stop_channel(i, val&0x4000);
1.265 }
1.266 }
1.267
1.268 @@ -343,22 +343,22 @@
1.269 * Derived directly from Dan Potter's log table
1.270 */
1.271 uint8_t aica_volume_table[256] = {
1.272 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1.273 - 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
1.274 - 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
1.275 - 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
1.276 - 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
1.277 - 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
1.278 - 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
1.279 - 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
1.280 - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
1.281 - 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
1.282 - 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
1.283 - 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
1.284 - 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
1.285 - 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
1.286 - 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
1.287 - 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
1.288 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1.289 + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
1.290 + 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9,
1.291 + 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
1.292 + 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
1.293 + 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
1.294 + 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
1.295 + 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
1.296 + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81,
1.297 + 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 100,
1.298 + 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
1.299 + 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
1.300 + 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
1.301 + 171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
1.302 + 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
1.303 + 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
1.304
1.305
1.306 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val )
1.307 @@ -367,58 +367,58 @@
1.308 audio_channel_t channel = audio_get_channel(channelNo);
1.309 switch( reg ) {
1.310 case 0x00: /* Config + high address bits*/
1.311 - channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
1.312 - if( val & 0x200 )
1.313 - channel->loop = LOOP_ON;
1.314 - else
1.315 - channel->loop = LOOP_OFF;
1.316 - switch( (val >> 7) & 0x03 ) {
1.317 - case 0:
1.318 - channel->sample_format = AUDIO_FMT_16BIT;
1.319 - break;
1.320 - case 1:
1.321 - channel->sample_format = AUDIO_FMT_8BIT;
1.322 - break;
1.323 - case 2:
1.324 - case 3:
1.325 - channel->sample_format = AUDIO_FMT_ADPCM;
1.326 - break;
1.327 - }
1.328 - if( val & 0x8000 ) {
1.329 - aica_start_stop_channels();
1.330 - }
1.331 - break;
1.332 - case 0x04: /* Low 16 address bits */
1.333 - channel->start = (channel->start & 0x001F0000) | val;
1.334 - break;
1.335 - case 0x08: /* Loop start */
1.336 - channel->loop_start = val;
1.337 - break;
1.338 - case 0x0C: /* End */
1.339 - channel->end = val;
1.340 - break;
1.341 - case 0x10: /* Envelope register 1 */
1.342 - break;
1.343 - case 0x14: /* Envelope register 2 */
1.344 - break;
1.345 - case 0x18: /* Frequency */
1.346 - channel->sample_rate = aica_frequency_to_sample_rate ( val );
1.347 - break;
1.348 - case 0x1C: /* ??? */
1.349 - case 0x20: /* ??? */
1.350 - case 0x24: /* Volume? /pan */
1.351 - val = val & 0x1F;
1.352 - if( val <= 0x0F )
1.353 - val = 0x0F - val; /* Convert to smooth pan over 0..31 */
1.354 - channel->pan = val;
1.355 - break;
1.356 - case 0x28: /* Volume */
1.357 - // This isn't remotely correct, but it will have to suffice until I have
1.358 - // time to figure out what's actually going on here...
1.359 - channel->vol = aica_volume_table[max((val & 0xFF),((val>>8)&0xFF))];
1.360 - break;
1.361 - default: /* ??? */
1.362 - break;
1.363 + channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
1.364 + if( val & 0x200 )
1.365 + channel->loop = LOOP_ON;
1.366 + else
1.367 + channel->loop = LOOP_OFF;
1.368 + switch( (val >> 7) & 0x03 ) {
1.369 + case 0:
1.370 + channel->sample_format = AUDIO_FMT_16BIT;
1.371 + break;
1.372 + case 1:
1.373 + channel->sample_format = AUDIO_FMT_8BIT;
1.374 + break;
1.375 + case 2:
1.376 + case 3:
1.377 + channel->sample_format = AUDIO_FMT_ADPCM;
1.378 + break;
1.379 + }
1.380 + if( val & 0x8000 ) {
1.381 + aica_start_stop_channels();
1.382 + }
1.383 + break;
1.384 + case 0x04: /* Low 16 address bits */
1.385 + channel->start = (channel->start & 0x001F0000) | val;
1.386 + break;
1.387 + case 0x08: /* Loop start */
1.388 + channel->loop_start = val;
1.389 + break;
1.390 + case 0x0C: /* End */
1.391 + channel->end = val;
1.392 + break;
1.393 + case 0x10: /* Envelope register 1 */
1.394 + break;
1.395 + case 0x14: /* Envelope register 2 */
1.396 + break;
1.397 + case 0x18: /* Frequency */
1.398 + channel->sample_rate = aica_frequency_to_sample_rate ( val );
1.399 + break;
1.400 + case 0x1C: /* ??? */
1.401 + case 0x20: /* ??? */
1.402 + case 0x24: /* Volume? /pan */
1.403 + val = val & 0x1F;
1.404 + if( val <= 0x0F )
1.405 + val = 0x0F - val; /* Convert to smooth pan over 0..31 */
1.406 + channel->pan = val;
1.407 + break;
1.408 + case 0x28: /* Volume */
1.409 + // This isn't remotely correct, but it will have to suffice until I have
1.410 + // time to figure out what's actually going on here...
1.411 + channel->vol = aica_volume_table[max((val & 0xFF),((val>>8)&0xFF))];
1.412 + break;
1.413 + default: /* ??? */
1.414 + break;
1.415 }
1.416
1.417 }
.