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

📄 taitosnd.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************//*                                                                            *//*            TAITO SOUND SYSTEMS (C) 1986-1996 TAITO CORPORATION             *//*                                                                            *//******************************************************************************//*answer of hiroshi-----------------YM30?? series is Serial DAC convertor. FM chip output is Serial DAC.This DAC input to YM30??. It change to Analog data.Antiriad: Thanks!!Changes-------17-02-99:- Reduce volume of YM2151 emulation.11-02-99:- z80 emulator and banking was changed some days ago...- added tc0140syt_reset() calls.18-01-99:- tc0140syt emulation is moved to tc140syt.c/h.14-01-99:- Merge changes from Hiroshi source (M6295 bank, ym2151: reg -> reg2151).09-01-99:- Add debug message if 68000 sends data before z80 has read the current  data.27-12-98:- Add Hiroshi changes (Volume and Panning).- What is YM3016? Is this the chip for panning/volume control?17-12-98:- Added latest Hiro-Shi changes.- Removed YM2610_Frame(), no longer needed.- Removed Z80 debug as there is already Z80 bad read/write/io routines  in mz80help.c.16-12-98:- Added YM2203 (Taito B-System). Used by Master of Weapons etc...*/#include "gameinc.h"#include "taitosnd.h"#include "fm.h"#ifdef RAINE_DEBUG#include "debug.h"#endif#include "sasound.h"		// sample support routinesstatic UINT8 *ROMBANK=NULL;	// Pointer to start of z80 rom bank datastatic UINT8 *BANKLIST[8];	// Pointers to start of each bank (0-7)static int curr_bank;/************************************************************/// YM2151 Handler// --------------static int reg2151;UINT16 YM2151ReadZ80(UINT16 offset){#if 0  if( (offset&0x01) ){    return YM2151_status_port_0_r(0);  } else    return 0;#else    static int ta=0;  ta^=255;  return(ta);  #endif}UINT16 YM2151ReadZ80_Timer(UINT16 offset){#if 1  if( (offset&0x01) ){    return YM2151_status_port_0_r(0);  } else    return 0;#else    static int ta=0;  ta^=255;  return(ta);  #endif}void YM2151WriteZ80(UINT16 offset, UINT8 data){   if((offset&1)==0){      reg2151=data;   }   else{     YM2151_register_port_0_w(offset,reg2151);	// It's faster to wait for the data like this!!     YM2151_data_port_0_w(offset,data);   }}// Banking via YM2151 - TAITOvoid YM2151TaitoWriteZ80(UINT16 offset, UINT8 data){   if((offset&1)==0){      reg2151=data;   }   else{      if(reg2151==0x1B){         TaitoSoundSetBank(offset, (UINT8) ((data>>6)&3) );      }      YM2151_register_port_0_w(offset,reg2151);	// It's faster to wait for the data like this!!      YM2151_data_port_0_w(offset,data);   }}/************************************************************/// YM2203A Handler// ---------------UINT16 YM2203AReadZ80(UINT16 offset){   #if 0   if((offset&1)==0){      return YM2203_status_port_0_r(0);   }   else{      return YM2203_read_port_0_r(0);   }   #else   static int ta=0;   ta^=255;   return(ta);   #endif}void YM2203AWriteZ80(UINT16 offset, UINT8 data){   static int reg;   if((offset&1)==0){      reg=data;   }   else{      YM2203_control_port_0_w(offset,reg);      YM2203_write_port_0_w(offset,data);   }}// Banking via YM2203 - TAITOvoid YM2203ATaitoWriteZ80(UINT16 offset, UINT8 data){   static int reg;   if((offset&1)==0){      reg=data;   }   else{      if(reg==0x0E){         TaitoSoundSetBank(offset, (UINT8) (data&3) );      }      YM2203_control_port_0_w(offset,reg);      YM2203_write_port_0_w(offset,data);   }}// YM2203A Handler// ---------------UINT16 YM2203BReadZ80(UINT16 offset){   #if 0   if((offset&1)==0){      return YM2203_status_port_1_r(0);   }   else{      return YM2203_read_port_1_r(0);   }   #else	// Cadash and Rainbow Extra only work with this code>>>   static int ta=0;   ta^=255;   return(ta);   #endif}void YM2203BWriteZ80(UINT16 offset, UINT8 data){   static int reg;   if((offset&1)==0){      reg=data;   }   else{      YM2203_control_port_1_w(offset,reg);      YM2203_write_port_1_w(offset,data);   }}/************************************************************ Taito Z80+YM2610 Interface -------------------------- For 99% of Taito sound Z80s using a YM2610************************************************************/// YM2610 Handler// --------------UINT16 YM2610ReadZ80(UINT16 offset){#if 1  switch(offset&3){  case 0x00: return(YM2610_status_port_0_A_r(offset));  case 0x01: return(YM2610_read_port_0_r(offset));  case 0x02: return(YM2610_status_port_0_B_r(offset));  default:   return(YM2610_read_port_0_r(offset));  }#else    static int ta=0;  ta^=255;  return(ta);  #endif}UINT16 YM2610ReadZ80SP(UINT16 offset){  // Speed patch  static int ta = 0;  switch(offset&3){  case 0x00:    ta ^= 0x03;    return YM2610_status_port_0_A_r(offset) | ta;    //return(YM2610_status_port_0_A_r(offset));      case 0x02: return(YM2610_status_port_0_B_r(offset));  break;  default:   return(YM2610_read_port_0_r(offset));    break;  }}void YM2610WriteZ80(UINT16 offset, UINT8 data){   switch(offset&3){      case 0x00: YM2610_control_port_0_A_w(offset,data); break;      case 0x01: YM2610_data_port_0_A_w(offset,data);    break;      case 0x02: YM2610_control_port_0_B_w(offset,data); break;      default:   YM2610_data_port_0_B_w(offset,data);    break;   }}static int taitoym2610pan[4];void Pan2610WriteZ80(UINT16 offset, UINT8 data){  int vol, pan, cen;  taitoym2610pan[offset&0x03] = data&0x00ff;  if( !(offset&0x02) ){    /**** channel 0 (YM3016 Left channel) ****/    if( taitoym2610pan[0] > taitoym2610pan[1] )  pan = taitoym2610pan[0];    else                                         pan = taitoym2610pan[1];    vol = (taitoym2610pan[0] + taitoym2610pan[1]) / 2;    if( pan ){      pan = 0x80 + (((0x7f00/pan) * (taitoym2610pan[0] - taitoym2610pan[1]))>>8);      cen = pan < 0x80 ? 0x80 - pan : -(0x80 - pan);      vol = vol - ((vol * cen)>>(8));      // vol is sometimes 0x1f. It is a bad mapping      if (vol == 0x1f) vol = 0xff;      saSetVolume( YM2610_get_stream_num(0), vol );      saSetPan( YM2610_get_stream_num(0), pan );      //print_ingame(120,"Make ch0 vol:%02x pan:%02x", vol, pan );    } else{      if (vol == 0x1f) vol = 0xff;      saSetVolume( YM2610_get_stream_num(0), vol>>1 );      saSetPan( YM2610_get_stream_num(0), 0x80 ); /* center */    }  } else{    /**** channel 1 (YM3016 Right channel) ****/    if( taitoym2610pan[2] > taitoym2610pan[3] )  pan = taitoym2610pan[2];    else                                         pan = taitoym2610pan[3];    vol = (taitoym2610pan[2] + taitoym2610pan[3]) / 2;    if( pan ){      pan = 0x80 + (((0x7f00/pan) * (taitoym2610pan[2] - taitoym2610pan[3]))>>8);      cen = pan < 0x80 ? 0x80 - pan : -(0x80 - pan);      vol = vol - ((vol * cen)>>(8));      if (vol == 0x1f) vol = 0xff;      saSetVolume( YM2610_get_stream_num(0)+1, vol );      saSetPan( YM2610_get_stream_num(0)+1, pan );      //print_ingame(120,"Make ch1 vol:%02x pan:%02x", vol, pan );    } else{      if (vol == 0x1f) vol = 0xff;      saSetVolume( YM2610_get_stream_num(0)+1, vol>>1 );      saSetPan( YM2610_get_stream_num(0)+1, 0x80 ); /* center */    }  }}static int volume_offset;void Pan2610_OffsetVol( int data ){  volume_offset = data;}void Pan2610WriteZ80_OffsetVol(UINT16 offset, UINT8 data){  int vol, pan, cen;  taitoym2610pan[offset&0x03] = data&0x00ff;  if( !(offset&0x02) ){    /**** channel 0 (YM3016 Left channel) ****/    if( taitoym2610pan[0] > taitoym2610pan[1] )  pan = taitoym2610pan[0];    else                                         pan = taitoym2610pan[1];    vol = ((taitoym2610pan[0] + taitoym2610pan[1]) / 2)<<volume_offset;    if( pan ){      pan = 0x80 + (((0x7f00/pan) * (taitoym2610pan[0] - taitoym2610pan[1]))>>8);      cen = pan < 0x80 ? 0x80 - pan : -(0x80 - pan);      vol = vol - ((vol * cen)>>(8));      if (vol == 0x1f) vol = 0xff;      saSetVolume( YM2610_get_stream_num(0), vol );      saSetPan( YM2610_get_stream_num(0), pan );      //print_ingame(120,"Make ch0 vol:%02x pan:%02x", vol, pan );    } else{      if (vol == 0x1f) vol = 0xff;      saSetVolume( YM2610_get_stream_num(0), vol>>1 );      saSetPan( YM2610_get_stream_num(0), 0x80 ); /* center */    }  } else{    /**** channel 1 (YM3016 Right channel) ****/    if( taitoym2610pan[2] > taitoym2610pan[3] )  pan = taitoym2610pan[2];    else                                         pan = taitoym2610pan[3];    vol = ((taitoym2610pan[2] + taitoym2610pan[3]) / 2)<<volume_offset;    if( pan ){      pan = 0x80 + (((0x7f00/pan) * (taitoym2610pan[2] - taitoym2610pan[3]))>>8);      cen = pan < 0x80 ? 0x80 - pan : -(0x80 - pan);      vol = vol - ((vol * cen)>>(8));      if (vol == 0x1f) vol = 0xff;      saSetVolume( YM2610_get_stream_num(0)+1, vol );      saSetPan( YM2610_get_stream_num(0)+1, pan );      //print_ingame(120,"Make ch1 vol:%02x pan:%02x", vol, pan );    } else{      if (vol == 0x1f) vol = 0xff;      saSetVolume( YM2610_get_stream_num(0)+1, vol>>1 );      saSetPan( YM2610_get_stream_num(0)+1, 0x80 ); /* center */    }  }}static UINT8 TYM = 0x07;UINT16 TaitoYM2610Test(UINT16 offset){  return TYM;}static struct YM2610interface ym2610_interface ={  1,  8000000,  { YM2203_VOL(220,220) },  { 0 },  { 0 },  { 0 },  { 0 },  { NULL },  { 0 },			// hiro-shi  { 1 },			// hiro-shi  { YM3012_VOL(255,OSD_PAN_LEFT,255,OSD_PAN_RIGHT) },};struct SOUND_INFO taito_ym2610_sound[] ={   { SOUND_YM2610,  &ym2610_interface,  },   { 0,             NULL,               },};struct SOUND_INFO taito_ym2610b_sound[] ={   { SOUND_YM2610B, &ym2610_interface,  },   { 0,             NULL,               },};/**** not pan control (lock volume) ****/void Taito2610_Frame(void){  //cpu_execute_cycles(CPU_Z80_0, (4000000/60)*2);			// Sound Z80  cpu_execute_cycles(CPU_Z80_0, 6000000/60);			// Sound Z80  /*#ifdef RAINE_DEBUG    print_debug("Z80PC0:%04x\n",z80pc);    #endif*/  cpu_interrupt(CPU_Z80_0, 0x0038);  #if 0    // REALLY useless !!!  saSetVolume( YM2610_get_stream_num(0), 0xaf );  saSetPan( YM2610_get_stream_num(0), 0x00 );  saSetVolume( YM2610_get_stream_num(0)+1, 0xaf );  saSetPan( YM2610_get_stream_num(0)+1, 0xff );#endif  }/**** pan control type (Darius2/NinjaWarriors board. but not use ninjaw.) ****/void Taito2610_FramePan(void){  cpu_execute_cycles(CPU_Z80_0, (4000000/60)*2);			// Sound Z80  /*#ifdef RAINE_DEBUG    print_debug("Z80PC0:%04x\n",z80pc);    #endif*/  cpu_interrupt(CPU_Z80_0, 0x0038);}

⌨️ 快捷键说明

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