Search
lxdream.org :: lxdream/src/aica/aica.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/aica.c
changeset 131:4c25f1b20664
prev106:9048bac046c3
next173:b006aaba9dff
author nkeynes
date Thu Mar 30 11:27:11 2006 +0000 (15 years ago)
permissions -rw-r--r--
last change Add basic AICA RTC implementation
view annotate diff log raw
     1 /**
     2  * $Id: aica.c,v 1.18 2006-03-30 11:27:11 nkeynes Exp $
     3  * 
     4  * This is the core sound system (ie the bit which does the actual work)
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     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.
    12  *
    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.
    17  */
    19 #define MODULE aica_module
    21 #include <time.h>
    22 #include "dream.h"
    23 #include "dreamcast.h"
    24 #include "mem.h"
    25 #include "aica/aica.h"
    26 #include "armcore.h"
    27 #include "aica/audio.h"
    28 #define MMIO_IMPL
    29 #include "aica.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 /**
    48  * Initialize the AICA subsystem. Note requires that 
    49  */
    50 void aica_init( void )
    51 {
    52     register_io_regions( mmio_list_spu );
    53     MMIO_NOTRACE(AICA0);
    54     MMIO_NOTRACE(AICA1);
    55     arm_mem_init();
    56     aica_reset();
    57 }
    59 void aica_reset( void )
    60 {
    61     arm_reset();
    62     aica_event(2); /* Pre-deliver a timer interrupt */
    63 }
    65 void aica_start( void )
    66 {
    68 }
    70 /**
    71  * Keep track of what we've done so far this second, to try to keep the
    72  * precision of samples/second.
    73  */
    74 int samples_done = 0;
    75 uint32_t nanosecs_done = 0;
    77 uint32_t aica_run_slice( uint32_t nanosecs )
    78 {
    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;
    88     }
    89     if( nanosecs_done > 1000000000 ) {
    90 	samples_done -= AICA_SAMPLE_RATE;
    91 	nanosecs_done -= 1000000000;
    92     }
    93     return nanosecs;
    94 }
    96 void aica_stop( void )
    97 {
    99 }
   101 void aica_save_state( FILE *f )
   102 {
   103     arm_save_state( f );
   104 }
   106 int aica_load_state( FILE *f )
   107 {
   108     return arm_load_state( f );
   109 }
   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.
   116  */
   118 void aica_event( int event )
   119 {
   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 );
   127 }
   129 void aica_clear_event( )
   130 {
   131     aica_clear_count++;
   132     if( aica_clear_count == 4 ) {
   133 	int i;
   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);
   139 		break;
   140 	    }
   141 	}
   142 	for( ;i<8; i++ ) {
   143 	    if( aica_event_pending & (1<<i) ) {
   144 		MMIO_WRITE( AICA2, AICA_IRQ, i );
   145 		break;
   146 	    }
   147 	}
   148 	if( aica_event_pending == 0 )
   149 	    armr.int_pending &= ~CPSR_F;
   150     }
   151 }
   153 void aica_enable( void )
   154 {
   155     mmio_region_AICA2_write( AICA_RESET, MMIO_READ(AICA2,AICA_RESET) & ~1 );
   156 }
   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
   164  * 14  4  Init to 0x1F
   165  * 18  4  Frequency (floating point)
   166  * 1C  4  ?? 
   167  * 20  4  ??
   168  * 24  1  Pan
   169  * 25  1  ??
   170  * 26  
   171  * 27  
   172  * 28  1  ??
   173  * 29  1  Volume
   174  * 2C
   175  * 30
   176  * 
   178 /* Write to channels 0-31 */
   179 void mmio_region_AICA0_write( uint32_t reg, uint32_t val )
   180 {
   181     MMIO_WRITE( AICA0, reg, val );
   182     aica_write_channel( reg >> 7, reg % 128, val );
   183     //    DEBUG( "AICA0 Write %08X => %08X", val, reg );
   184 }
   186 /* Write to channels 32-64 */
   187 void mmio_region_AICA1_write( uint32_t reg, uint32_t val )
   188 {
   189     MMIO_WRITE( AICA1, reg, val );
   190     aica_write_channel( (reg >> 7) + 32, reg % 128, val );
   191     // DEBUG( "AICA1 Write %08X => %08X", val, reg );
   192 }
   194 /**
   195  * AICA control registers 
   196  */
   197 void mmio_region_AICA2_write( uint32_t reg, uint32_t val )
   198 {
   199     uint32_t tmp;
   200     switch( reg ) {
   201     case AICA_RESET:
   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" );
   206 	    arm_reset();
   207 	    samples_done = 0;
   208 	    nanosecs_done = 0;
   209 	} else if( (tmp&1) == 0 && (val&1) == 1 ) {
   210 	    DEBUG( "ARM disabled" );
   211 	}
   212 	MMIO_WRITE( AICA2, AICA_RESET, val );
   213 	break;
   214     case AICA_IRQCLEAR:
   215 	aica_clear_event();
   216 	break;
   217     default:
   218 	MMIO_WRITE( AICA2, reg, val );
   219 	break;
   220     }
   221 }
   223 /* 20 years in seconds */
   224 #define RTC_OFFSET 631152000
   226 int32_t mmio_region_AICARTC_read( uint32_t reg )
   227 {
   228     struct timeval tv;
   230     switch( reg ) {
   231     case AICA_RTCHI:
   232 	if( gettimeofday( &tv, NULL ) == 0 ) {
   233 	    return ((uint32_t)(tv.tv_sec + RTC_OFFSET)) >> 16;
   234 	}
   235 	break;
   236     case AICA_RTCLO:
   237 	if( gettimeofday( &tv, NULL ) == 0 ) {
   238 	    return ((uint32_t)(tv.tv_sec + RTC_OFFSET)) & 0xFFFF;
   239 	}
   240 	break;
   241     }
   242     return 0;
   243 }
   245 MMIO_REGION_WRITE_STUBFN( AICARTC )
   247 /**
   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
   251  * be unused.
   252  *
   253  * @return sample rate in samples per second.
   254  */
   255 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
   256 {
   257     uint32_t exponent = (freq & 0x3800) >> 11;
   258     uint32_t mantissa = freq & 0x03FF;
   259     uint32_t rate;
   260     if( freq & 0x4000 ) {
   261 	/* neg exponent - rate < 44100 */
   262 	exponent = 8 - exponent;
   263 	rate = (44100 >> exponent) +
   264 	    ((44100 * mantissa) >> (10+exponent));
   265     } else {
   266 	/* pos exponent - rate > 44100 */
   267 	rate = (44100 << exponent) +
   268 	    ((44100 * mantissa) >> (10-exponent));
   269     }
   270     return rate;
   271 }
   273 /**
   274  * Derived directly from Dan Potter's log table
   275  */
   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 ) 
   296 {
   297     val &= 0x0000FFFF;
   298     audio_channel_t channel = audio_get_channel(channelNo);
   299     switch( reg ) {
   300     case 0x00: /* Config + high address bits*/
   301 	channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
   302 	if( val & 0x200 ) 
   303 	    channel->loop = TRUE;
   304 	else 
   305 	    channel->loop = FALSE;
   306 	switch( (val >> 7) & 0x03 ) {
   307 	case 0:
   308 	    channel->sample_format = AUDIO_FMT_16BIT;
   309 	    break;
   310 	case 1:
   311 	    channel->sample_format = AUDIO_FMT_8BIT;
   312 	    break;
   313 	case 2:
   314 	case 3:
   315 	    channel->sample_format = AUDIO_FMT_ADPCM;
   316 	    break;
   317 	}
   318 	switch( (val >> 14) & 0x03 ) {
   319 	case 2: 
   320 	    audio_stop_channel( channelNo ); 
   321 	    break;
   322 	case 3: 
   323 	    audio_start_channel( channelNo ); 
   324 	    break;
   325 	default:
   326 	    break;
   327 	    /* Hrmm... */
   328 	}
   329 	break;
   330     case 0x04: /* Low 16 address bits */
   331 	channel->start = (channel->start & 0x001F0000) | val;
   332 	break;
   333     case 0x08: /* Loop start */
   334 	channel->loop_start = val;
   335 	break;
   336     case 0x0C: /* End */
   337 	channel->end = val;
   338 	break;
   339     case 0x10: /* Envelope register 1 */
   340 	break;
   341     case 0x14: /* Envelope register 2 */
   342 	break;
   343     case 0x18: /* Frequency */
   344 	channel->sample_rate = aica_frequency_to_sample_rate ( val );
   345 	break;
   346     case 0x1C: /* ??? */
   347     case 0x20: /* ??? */
   348     case 0x24: /* Volume? /pan */
   349 	val = val & 0x1F;
   350 	if( val <= 0x0F ) 
   351 	    val = 0x0F - val; /* Convert to smooth pan over 0..31 */
   352 	channel->pan = val;
   353 	break;
   354     case 0x28: /* Volume */
   355 	channel->vol = aica_volume_table[val & 0xFF];
   356 	break;
   357     default: /* ??? */
   358 	break;
   359     }
   361 }
.