⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msm5205.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
字号:
/**************************************************************//*   MSM5205 (DARIUS ADPCM chip) control                      *//**************************************************************/#include "raine.h"#include "sasound.h"#include "msm5205.h"#ifdef RAINE_DEBUG#include "debug.h"#endifstatic struct MSM5205buffer_interface *intf;typedef struct M5205_SAMPLE{   UINT32 len;                  	// length (in samples?)   INT16 *data;                  // sample data (16 bit?)} M5205_SAMPLE;struct msm5205buffer_chip{  int    sample_rate;  int    now_reqcode;  struct M5205_SAMPLE *samp;  int    stream;  int    req_len;  INT16  *req_buf;  int    req_vol;  int    offset, add;  INT16  *decode_area;};struct msm5205buffer_chip *MSM5205buffer_chip = NULL;static int chip_num = 0;static int emu_rate, buf_len;static int sample_len;#define UPDATE_SHIFT (8)static INLINE int aLimit( int val, int max, int min ){  if ( val > max )    val = max;  else if ( val < min )    val = min;  return val;}/**************************************************//*    decode control                              *//**************************************************/static int ad_sample;static int ad_index;static int ad_index_table[8] = {  -1, -1, -1, -1, 2, 4, 6, 8};static int ad_offset_table[49]= {  0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001c, 0x001f,  0x0022, 0x0025, 0x0029, 0x002d, 0x0032, 0x0037, 0x003c, 0x0042,  0x0049, 0x0050, 0x0058, 0x0061, 0x006b, 0x0076, 0x0082, 0x008f,  0x009d, 0x00ad, 0x00be, 0x00d1, 0x00e6, 0x00fd, 0x0117, 0x0133,  0x0151, 0x0173, 0x0198, 0x01c1, 0x01ee, 0x0220, 0x0256, 0x0292,  0x02d4, 0x031c, 0x036c, 0x03c3, 0x0424, 0x048e, 0x0502, 0x0583,  0x0610};static void ad_decode(int ad_code){  int ad_base;  int ad_offset;  ad_base   = ad_offset_table[ad_index];  ad_offset = ad_base/8;    if( ad_code&0x01 )  ad_offset += ad_base>>2;  if( ad_code&0x02 )  ad_offset += ad_base>>1;  if( ad_code&0x04 )  ad_offset += ad_base;  if( ad_code&0x08 )  ad_offset  = 0 - ad_offset;  ad_sample = aLimit( ad_sample + ad_offset, 2047, -2048 );  ad_index = aLimit( ad_index + ad_index_table[ad_code&7], 48, 0 );}/**************************************************//*    rom decode                                  *//**************************************************/static unsigned int err_table;static int   decode_table_count;static unsigned int *decode_table;static int   decode_area_size;static INT16 *decode_area;void MSM5205_decode( int i, struct M5205_SAMPLE *samp, UINT8 *rom, UINT32 romsize, UINT32 start, UINT32 stop ){  INT16 *ad_data;  /**** table initial ****/  samp->len        = 0;  samp->data       = NULL;  /*************************************************/  if( stop >= romsize )  stop = romsize;#ifdef RAINE_DEBUG  print_debug( "Now decode No.%d %08x-%08x\n", i, start, stop );#endif  if((start<romsize) && (stop<romsize)){	// Add Antiriad (Kick Off needs it)        if( (start < stop) &&	!(start == 0x00808080 || start == 0x00080808 ||	  stop == 0x00808080 || stop == 0x00080808) ){      /**** low limit address check ****/      if( start < err_table )  err_table = start;      samp->len = (stop - start)*2; /* get length (1byte = 2 data) */      /**** new decode routine ****/      {	int  count, j;	count = decode_table_count;	for( j = 0; j < count; j++ ){#if 0	  if( start == *(decode_table + j*3) && stop <= *(decode_table + j*3 + 1) ){#ifdef RAINE_DEBUG	    print_debug( "Get decode table (%08x - %08x) [%08x-%08x]\n", start, stop, *(decode_table + j*3),  *(decode_table + j*3 + 1) );#endif	    samp->data = (void *)(*(decode_table + j*3 + 2)|0x80000000);	    return;	  }#else	  if( start >= *(decode_table + j*3) && stop <= *(decode_table + j*3 + 1) ){#ifdef RAINE_DEBUG	    print_debug( "Get decode table (%08x - %08x) [%08x-%08x]\n", start, stop, *(decode_table + j*3),  *(decode_table + j*3 + 1) );#endif	    samp->data = (void *)((*(decode_table + j*3 + 2) + (start - *(decode_table + j*3))*2)|0x80000000 );	    return;	  }#endif	}	/**** decode start ****/	*(decode_table + count*3)     = start;	*(decode_table + count*3 + 1) = stop;	*(decode_table + count*3 + 2) = decode_area_size;	decode_table_count++;#ifdef RAINE_DEBUG	print_debug( "New decode Address (%02x:%08x - %08x)\n", count, *(decode_table + count*3), *(decode_table + count*3 + 1) );#endif	decode_area = realloc( decode_area, (decode_area_size + samp->len) * sizeof(INT16) );	ad_data = (INT16 *)(decode_area + decode_area_size);	samp->data = (void *)(decode_area_size|0x80000000); /* rom offset */	decode_area_size += samp->len;	rom += start;	ad_sample = 0;		/* work init */	ad_index = 0;		/* work init */	for( start = 0; start < samp->len/2; start++ ){	  ad_decode( (*rom)>>4 );	  *ad_data++ = (INT16)(ad_sample<<4);	  ad_decode( (*rom)&0x0f );	  *ad_data++ = (INT16)(ad_sample<<4);	  rom++;	}      }    }  }}/**************************************************//*    sh start                                    *//**************************************************/int MSM5205buffer_sh_start( struct MSM5205buffer_interface *interface ){  int  num;  int  i;  char buf[2][40];  const char *name[2];  struct msm5205buffer_chip *mp;  int rate = audio_sample_rate;  intf = interface;  chip_num = intf->num;  sample_len  = rate / 60;  emu_rate = sample_len * 60;  if( chip_num > MSM5205BF_MAX )  return 1;  if( (MSM5205buffer_chip = (struct msm5205buffer_chip *)malloc( sizeof(struct msm5205buffer_chip) * chip_num )) == NULL )    return 1;  for( num = 0; num < chip_num; num++ ){    mp = MSM5205buffer_chip + num;    mp->now_reqcode = -1;    mp->sample_rate = intf->sample_rate[num];    mp->req_len = 0;    mp->req_vol = 0xff;    mp->add = (int)(((float)mp->sample_rate / (float)rate)*(1<<UPDATE_SHIFT));    if( intf->updatemode == MSM5205_MONO ){      sprintf( buf[0], "MSM5205 Monaural" );      mp->stream = stream_init( buf[0], emu_rate, 16, num, MSM5205buffer_UpdateOne );			// Antiriad: fix param num      saSetPan( mp->stream, 0x80 );      saSetVolume( mp->stream, intf->volume[num] );    }    else{      name[0] = buf[0];      name[1] = buf[1];      sprintf( buf[0], "MSM5205 Stereo Left" );      sprintf( buf[1], "MSM5205 Stereo Right" );      mp->stream = stream_init_multi( 2, name, emu_rate, 16, num, MSM5205buffer_Stereo_UpdateOne );	// Antiriad: fix param num      saSetPan( mp->stream, 0x00 );      saSetPan( mp->stream+1, 0xff );      saSetVolume( mp->stream, intf->volume[num] );      saSetVolume( mp->stream+1, intf->volume[num] );    }    mp->samp = (M5205_SAMPLE *)malloc( sizeof(M5205_SAMPLE) * intf->listsize[num] );    decode_table = malloc( (sizeof(unsigned int) * intf->listsize[num] * 3) );    if( mp->samp != NULL && decode_table != NULL ){      decode_table_count = 0;      decode_area  = NULL;      decode_area_size = 0;      for( i = 0; i < intf->listsize[num]; i++ ){	*(decode_table + i*3)     = 0xffffffff;	*(decode_table + i*3 + 1) = 0xffffffff;	*(decode_table + i*3 + 2) = 0x00000000;      }      for( i = 0; i < intf->listsize[num]; i++ )	MSM5205_decode( i, mp->samp + i, intf->rom[num], intf->romsize[num], (intf->list[num] + i)->start, (intf->list[num] + i)->end );      if( decode_area != NULL ){	mp->decode_area  = decode_area;	/* stock work */	for( i = 0; i < intf->listsize[num]; i++ ){	  if( ((unsigned int)(mp->samp + i)->data)&0x80000000 )	    (mp->samp + i)->data = decode_area + (((unsigned int)(mp->samp + i)->data)&0x7fffffff);	  /**** 0x8xxxxxxx is use flag ****/	}      }      else{	mp->decode_area = NULL;      }      /**** end of decode ****/      free( decode_table );    }  }  return 0;}/**************************************************//**************************************************/void MSM5205buffer_sh_stop( void ){   int i;   struct msm5205buffer_chip *mp;   if( MSM5205buffer_chip == NULL )  return;   for( i = 0; i < chip_num; i++ ){      mp = MSM5205buffer_chip + i;      if(mp->samp != NULL) free(mp->samp);			// Antiriad 06-04-99      if(mp->decode_area != NULL) free(mp->decode_area);   }   if(MSM5205buffer_chip != NULL) free(MSM5205buffer_chip);	// Antiriad 06-04-99   MSM5205buffer_chip = NULL;   chip_num = 0;}/**************************************************//*    sh update                                   *//**************************************************/void MSM5205buffer_UpdateOne( int num, void *buffer, int length ){  int  i, addr, bf_len;  INT16 *sp =NULL, *dsp = NULL;  struct msm5205buffer_chip *mp;  if( num >= chip_num )  return;			// Antiriad: replace > with >=  mp = MSM5205buffer_chip + num;  sp = (INT16 *)buffer;  dsp = mp->req_buf;  buf_len = length * 2;  bf_len = length;    if( mp->now_reqcode == -1 ){    memset( buffer, 0, buf_len );  } else{    for( i = 0; i < bf_len; i++ ){      addr = mp->offset>>UPDATE_SHIFT;      if( addr >= mp->req_len ){	memset( sp, 0, (bf_len - i)*2 );	mp->now_reqcode = -1;		/* end ADPCM */	break;      }      *sp++ = *(dsp + addr);      mp->offset += mp->add;    }  }}/**************************************************//*    sh update                                   *//**************************************************/void MSM5205buffer_Stereo_UpdateOne( int num, void **buffer, int length ){  int  i, addr, bf_len;  INT16 *sp = NULL, *sp2 = NULL, *dsp = NULL;  int lv, rv;  struct msm5205buffer_chip *mp;    if( num >= chip_num )  return;			// Antiriad: replace > with >=  mp = MSM5205buffer_chip + num;  lv = mp->req_vol&0xf0;  rv = (mp->req_vol&0x0f)<<4;  buf_len = length * 2;  sp  = (INT16 *)buffer[0];  sp2 = (INT16 *)buffer[1];  dsp = mp->req_buf;  bf_len = buf_len / 2;    if( mp->now_reqcode == -1 ){    memset( sp, 0, bf_len*sizeof(short) );    memset( sp2, 0, bf_len*sizeof(short) );  } else{    for( i = 0; i < bf_len; i++ ){      addr = mp->offset>>UPDATE_SHIFT;      if( addr >= mp->req_len ){	memset(  sp, 0, (bf_len - i)*2 );	memset( sp2, 0, (bf_len - i)*2 );	mp->now_reqcode = -1;		/* end ADPCM */	break;      }      *sp++  = (((int)*(dsp + addr)) * lv)>>8;      *sp2++ = (((int)*(dsp + addr)) * rv)>>8;      mp->offset += mp->add;    }  }}/**************************************************//*    ADPCM request                               *//**************************************************/void MSM5205buffer_request( int num, int code ){  struct msm5205buffer_chip *mp;    if( num >= chip_num )  return;			// Antiriad: replace > with >=  mp = MSM5205buffer_chip + num;  if(! mp->samp )  return;					// Antiriad ??-??-99  mp->now_reqcode = code;  mp->req_buf = mp->samp[code].data;  mp->req_len = mp->samp[code].len;  mp->offset = 0;}/**************************************************//*    ADPCM pan request                           *//**************************************************/void MSM5205buffer_setpan( int num, int data ){  struct msm5205buffer_chip *mp;    if( num >= chip_num )  return;			// Antiriad: replace > with >=  mp = MSM5205buffer_chip + num;  mp->req_vol = data;}/**************** end of file ****************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -