Search
lxdream.org :: lxdream/src/aica/aica.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/aica.c
changeset 934:3acd3b3ee6d1
prev929:fd8cb0c82f5f
next1067:d3c00ffccfcd
author nkeynes
date Wed Jan 07 04:39:58 2009 +0000 (15 years ago)
branchlxdream-mem
permissions -rw-r--r--
last change Add missed file from previous commit - remove sh4_translate_flush_cache, change
exit to use pre-recovery
view annotate diff log raw
     1 /**
     2  * $Id$
     3  * 
     4  * This module implements the AICA's IO interfaces, as well
     5  * as providing the core AICA module to the system.
     6  *
     7  * Copyright (c) 2005 Nathan Keynes.
     8  *
     9  * This program is free software; you can redistribute it and/or modify
    10  * it under the terms of the GNU General Public License as published by
    11  * the Free Software Foundation; either version 2 of the License, or
    12  * (at your option) any later version.
    13  *
    14  * This program is distributed in the hope that it will be useful,
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17  * GNU General Public License for more details.
    18  */
    20 #define MODULE aica_module
    22 #include <time.h>
    23 #include "dream.h"
    24 #include "dreamcast.h"
    25 #include "mem.h"
    26 #include "aica/aica.h"
    27 #include "armcore.h"
    28 #include "aica/audio.h"
    29 #define MMIO_IMPL
    30 #include "aica.h"
    32 MMIO_REGION_READ_DEFFN( AICA0 )
    33 MMIO_REGION_READ_DEFFN( AICA1 )
    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 struct aica_state_struct {
    48     uint32_t time_of_day;
    49     /**
    50      * Keep track of what we've done so far this second, to try to keep the
    51      * precision of samples/second.
    52      */
    53     uint32_t samples_done;
    54     uint32_t nanosecs_done;
    55     /**
    56      * Event (IRQ) state
    57      */
    58     int event_pending;
    59     int clear_count;
    60 };
    62 static struct aica_state_struct aica_state;
    65 /**
    66  * Initialize the AICA subsystem. Note requires that 
    67  */
    68 void aica_init( void )
    69 {
    70     register_io_regions( mmio_list_spu );
    71     MMIO_NOTRACE(AICA0);
    72     MMIO_NOTRACE(AICA1);
    73     aica_reset();
    74 }
    76 void aica_reset( void )
    77 {
    78     arm_reset();
    79     aica_state.time_of_day = 0x5bfc8900;
    80     aica_state.samples_done = 0;
    81     aica_state.nanosecs_done = 0;
    82     aica_state.event_pending = 0;
    83     aica_state.clear_count = 0;
    84     //    aica_event(2); /* Pre-deliver a timer interrupt */
    85 }
    87 void aica_start( void )
    88 {
    90 }
    92 uint32_t aica_run_slice( uint32_t nanosecs )
    93 {
    94     /* Run arm instructions */
    95     int reset = MMIO_READ( AICA2, AICA_RESET );
    96     if( (reset & 1) == 0 ) { /* Running */
    97         int num_samples = (int)((uint64_t)AICA_SAMPLE_RATE * (aica_state.nanosecs_done + nanosecs) / 1000000000) - aica_state.samples_done;
    98         num_samples = arm_run_slice( num_samples );
    99         audio_mix_samples( num_samples );
   101         aica_state.samples_done += num_samples;
   102         aica_state.nanosecs_done += nanosecs;
   103     }
   104     if( aica_state.nanosecs_done > 1000000000 ) {
   105         aica_state.samples_done -= AICA_SAMPLE_RATE;
   106         aica_state.nanosecs_done -= 1000000000;
   107         aica_state.time_of_day++;
   108     }
   109     return nanosecs;
   110 }
   112 void aica_stop( void )
   113 {
   115 }
   117 void aica_save_state( FILE *f )
   118 {
   119     fwrite( &aica_state, sizeof(struct aica_state_struct), 1, f );
   120     arm_save_state( f );
   121     audio_save_state(f);
   122 }
   124 int aica_load_state( FILE *f )
   125 {
   126     fread( &aica_state, sizeof(struct aica_state_struct), 1, f );
   127     arm_load_state( f );
   128     return audio_load_state(f);
   129 }
   131 /* Note: This is probably not necessarily technically correct but it should
   132  * work in the meantime.
   133  */
   135 void aica_event( int event )
   136 {
   137     if( aica_state.event_pending == 0 )
   138         armr.int_pending |= CPSR_F;
   139     aica_state.event_pending |= (1<<event);
   141     int pending = MMIO_READ( AICA2, AICA_IRQ );
   142     if( pending == 0 || event < pending )
   143         MMIO_WRITE( AICA2, AICA_IRQ, event );
   144 }
   146 void aica_clear_event( )
   147 {
   148     aica_state.clear_count++;
   149     if( aica_state.clear_count == 4 ) {
   150         int i;
   151         aica_state.clear_count = 0;
   153         for( i=0; i<8; i++ ) {
   154             if( aica_state.event_pending & (1<<i) ) {
   155                 aica_state.event_pending &= ~(1<<i);
   156                 break;
   157             }
   158         }
   159         for( ;i<8; i++ ) {
   160             if( aica_state.event_pending & (1<<i) ) {
   161                 MMIO_WRITE( AICA2, AICA_IRQ, i );
   162                 break;
   163             }
   164         }
   165         if( aica_state.event_pending == 0 )
   166             armr.int_pending &= ~CPSR_F;
   167     }
   168 }
   170 void aica_enable( void )
   171 {
   172     mmio_region_AICA2_write( AICA_RESET, MMIO_READ(AICA2,AICA_RESET) & ~1 );
   173 }
   175 /** Channel register structure:
   176  * 00  4  Channel config
   177  * 04  4  Waveform address lo (16 bits)
   178  * 08  4  Loop start address
   179  * 0C  4  Loop end address
   180  * 10  4  Volume envelope
   181  * 14  4  Init to 0x1F
   182  * 18  4  Frequency (floating point)
   183  * 1C  4  ?? 
   184  * 20  4  ??
   185  * 24  1  Pan
   186  * 25  1  ??
   187  * 26  
   188  * 27  
   189  * 28  1  ??
   190  * 29  1  Volume
   191  * 2C
   192  * 30
   193  */
   195 /* Write to channels 0-31 */
   196 MMIO_REGION_WRITE_FN( AICA0, reg, val )
   197 {
   198     reg &= 0xFFF;
   199     MMIO_WRITE( AICA0, reg, val );
   200     aica_write_channel( reg >> 7, reg % 128, val );
   201     //    DEBUG( "AICA0 Write %08X => %08X", val, reg );
   202 }
   204 /* Write to channels 32-64 */
   205 MMIO_REGION_WRITE_FN( AICA1, reg, val )
   206 {
   207     reg &= 0xFFF;
   208     MMIO_WRITE( AICA1, reg, val );
   209     aica_write_channel( (reg >> 7) + 32, reg % 128, val );
   210     // DEBUG( "AICA1 Write %08X => %08X", val, reg );
   211 }
   213 /**
   214  * AICA control registers 
   215  */
   216 MMIO_REGION_WRITE_FN( AICA2, reg, val )
   217 {
   218     uint32_t tmp;
   219     reg &= 0xFFF;
   221     switch( reg ) {
   222     case AICA_RESET:
   223         tmp = MMIO_READ( AICA2, AICA_RESET );
   224         if( (tmp & 1) == 1 && (val & 1) == 0 ) {
   225             /* ARM enabled - execute a core reset */
   226             DEBUG( "ARM enabled" );
   227             arm_reset();
   228             aica_state.samples_done = 0;
   229             aica_state.nanosecs_done = 0;
   230         } else if( (tmp&1) == 0 && (val&1) == 1 ) {
   231             DEBUG( "ARM disabled" );
   232         }
   233         MMIO_WRITE( AICA2, AICA_RESET, val );
   234         break;
   235     case AICA_IRQCLEAR:
   236         aica_clear_event();
   237         break;
   238     case AICA_FIFOIN: /* Read-only */
   239         break;
   240     default:
   241         MMIO_WRITE( AICA2, reg, val );
   242         break;
   243     }
   244 }
   246 MMIO_REGION_READ_FN( AICA2, reg )
   247 {
   248     audio_channel_t channel;
   249     uint32_t channo;
   250     int32_t val;
   251     reg &= 0xFFF;
   252     switch( reg ) {
   253     case AICA_CHANSTATE:
   254         channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
   255         channel = audio_get_channel(channo);
   256         if( channel->loop == LOOP_LOOPED ) {
   257             val = 0x8000;
   258             channel->loop = LOOP_ON;
   259         } else {
   260             val = 0;
   261         }
   262         return val;
   263     case AICA_CHANPOSN:
   264         channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;
   265         channel = audio_get_channel(channo);
   266         return channel->posn;
   267     default:
   268         return MMIO_READ( AICA2, reg );
   269     }
   270 }
   272 MMIO_REGION_READ_FN( AICARTC, reg )
   273 {
   274     int32_t rv = 0;
   275     reg &= 0xFFF;
   276     switch( reg ) {
   277     case AICA_RTCHI:
   278         rv = (aica_state.time_of_day >> 16) & 0xFFFF;
   279         break;
   280     case AICA_RTCLO:
   281         rv = aica_state.time_of_day & 0xFFFF;
   282         break;
   283     }
   284     // DEBUG( "Read AICA RTC %d => %08X", reg, rv );
   285     return rv;
   286 }
   288 MMIO_REGION_WRITE_FN( AICARTC, reg, val )
   289 {
   290     reg &= 0xFFF;
   291     switch( reg ) {
   292     case AICA_RTCEN:
   293         MMIO_WRITE( AICARTC, reg, val&0x01 );
   294         break;
   295     case AICA_RTCLO:
   296         if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
   297             aica_state.time_of_day = (aica_state.time_of_day & 0xFFFF0000) | (val & 0xFFFF);
   298         }
   299         break;
   300     case AICA_RTCHI:
   301         if( MMIO_READ( AICARTC, AICA_RTCEN ) & 0x01 ) {
   302             aica_state.time_of_day = (aica_state.time_of_day & 0xFFFF) | (val<<16);
   303             MMIO_WRITE( AICARTC, AICA_RTCEN, 0 );
   304         }
   305         break;
   306     }
   307 }
   309 /**
   310  * Translate the channel frequency to a sample rate. The frequency is a
   311  * 14-bit floating point number, where bits 0..9 is the mantissa,
   312  * 11..14 is the signed exponent (-8 to +7). Bit 10 appears to
   313  * be unused.
   314  *
   315  * @return sample rate in samples per second.
   316  */
   317 uint32_t aica_frequency_to_sample_rate( uint32_t freq )
   318 {
   319     uint32_t exponent = (freq & 0x3800) >> 11;
   320     uint32_t mantissa = freq & 0x03FF;
   321     uint32_t rate;
   322     if( freq & 0x4000 ) {
   323         /* neg exponent - rate < 44100 */
   324         exponent = 8 - exponent;
   325         rate = (44100 >> exponent) +
   326         ((44100 * mantissa) >> (10+exponent));
   327     } else {
   328         /* pos exponent - rate > 44100 */
   329         rate = (44100 << exponent) +
   330         ((44100 * mantissa) >> (10-exponent));
   331     }
   332     return rate;
   333 }
   335 void aica_start_stop_channels()
   336 {
   337     int i;
   338     for( i=0; i<32; i++ ) {
   339         uint32_t val = MMIO_READ( AICA0, i<<7 );
   340         audio_start_stop_channel(i, val&0x4000);
   341     }
   342     for( ; i<64; i++ ) {
   343         uint32_t val = MMIO_READ( AICA1, (i-32)<<7 );
   344         audio_start_stop_channel(i, val&0x4000);
   345     }
   346 }
   348 /**
   349  * Derived directly from Dan Potter's log table
   350  */
   351 uint8_t aica_volume_table[256] = {
   352         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,
   353         1,   1,   1,   1,   1,   1,   2,   2,   2,   2,   2,   3,   3,   3,   3,   4,
   354         4,   4,   4,   5,   5,   5,   5,   6,   6,   6,   7,   7,   7,   8,   8,   9,
   355         9,   9,  10,  10,  11,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,
   356         16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  22,  22,  23,  23,  24,  25,
   357         25,  26,  27,  27,  28,  29,  29,  30,  31,  31,  32,  33,  34,  34,  35,  36,
   358         37,  37,  38,  39,  40,  40,  41,  42,  43,  44,  45,  45,  46,  47,  48,  49,
   359         50,  51,  52,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,
   360         65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  76,  77,  78,  79,  80,  81,
   361         82,  83,  85,  86,  87,  88,  89,  90,  92,  93,  94,  95,  97,  98,  99, 100,
   362         102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121,
   363         123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145,
   364         146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168, 170,
   365         171, 173, 175, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197,
   366         199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224, 226,
   367         228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 253, 254, 255 };
   370 void aica_write_channel( int channelNo, uint32_t reg, uint32_t val ) 
   371 {
   372     val &= 0x0000FFFF;
   373     audio_channel_t channel = audio_get_channel(channelNo);
   374     switch( reg ) {
   375     case 0x00: /* Config + high address bits*/
   376         channel->start = (channel->start & 0xFFFF) | ((val&0x1F) << 16);
   377         if( val & 0x200 ) 
   378             channel->loop = LOOP_ON;
   379         else 
   380             channel->loop = LOOP_OFF;
   381         switch( (val >> 7) & 0x03 ) {
   382         case 0:
   383             channel->sample_format = AUDIO_FMT_16BIT;
   384             break;
   385         case 1:
   386             channel->sample_format = AUDIO_FMT_8BIT;
   387             break;
   388         case 2:
   389         case 3:
   390             channel->sample_format = AUDIO_FMT_ADPCM;
   391             break;
   392         }
   393         if( val & 0x8000 ) {
   394             aica_start_stop_channels();
   395         }
   396         break;
   397         case 0x04: /* Low 16 address bits */
   398             channel->start = (channel->start & 0x001F0000) | val;
   399             break;
   400         case 0x08: /* Loop start */
   401             channel->loop_start = val;
   402             break;
   403         case 0x0C: /* End */
   404             channel->end = val;
   405             break;
   406         case 0x10: /* Envelope register 1 */
   407             break;
   408         case 0x14: /* Envelope register 2 */
   409             break;
   410         case 0x18: /* Frequency */
   411             channel->sample_rate = aica_frequency_to_sample_rate ( val );
   412             break;
   413         case 0x1C: /* ??? */
   414         case 0x20: /* ??? */
   415         case 0x24: /* Volume? /pan */
   416             val = val & 0x1F;
   417             if( val <= 0x0F ) 
   418                 val = 0x0F - val; /* Convert to smooth pan over 0..31 */
   419             channel->pan = val;
   420             break;
   421         case 0x28: /* Volume */
   422             // This isn't remotely correct, but it will have to suffice until I have
   423             // time to figure out what's actually going on here... 
   424             channel->vol = aica_volume_table[max((val & 0xFF),((val>>8)&0xFF))];
   425             break;
   426         default: /* ??? */
   427             break;
   428     }
   430 }
.