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

📄 es5506.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
📖 第 1 页 / 共 4 页
字号:
	//update_irq_state(chip);	//}      // (LOG_COMMANDS && eslog)      //fprintf(eslog, "%06x:voice %d, loop end=%08x\n", cpu_getpreviouspc(), chip->current_page & 0x1f, voice->end);      break;          case 0x06:	/* K2 */	voice->k2 = (voice->k2 & ~0x00f0) | (data & 0x00f0);	voice->k2 = (voice->k2 & ~0xff00) | (data & 0xff00);      break;          case 0x07:	/* K1 */	voice->k1 = (voice->k1 & ~0x00f0) | (data & 0x00f0);	voice->k1 = (voice->k1 & ~0xff00) | (data & 0xff00);      break;          case 0x08:	/* LVOL */	voice->lvol = (voice->lvol & ~0xff00) | (data & 0xff00);      break;          case 0x09:	/* RVOL */	voice->rvol = (voice->rvol & ~0xff00) | (data & 0xff00);      break;	    case 0x0a:	/* ACC (hi) */	voice->accum = (voice->accum & ~0x03fc0000) | ((data & 0x00ff) << 18);	voice->accum = (voice->accum & ~0x7c000000) | ((data & 0x1f00) << 18);	if (!(voice->control & CONTROL_STOPMASK))	  fprintf(stderr,"got it accum2\n");      break;	    case 0x0b:	/* ACC (lo) */	voice->accum = (voice->accum & ~0x000003fc) | ((data & 0x00ff) << 2);	voice->accum = (voice->accum & ~0x0003fc00) | ((data & 0xff00) << 2);	if (!(voice->control & CONTROL_STOPMASK))	  fprintf(stderr,"got it accum2bzz\n");      break;          case 0x0c:	/* unused */      break;          case 0x0d:	/* ACT */      {	  double sample_rate = chip->master_clock / (double)(16 * ((data & 0x1f) + 1));	  if (audio_sample_rate)	    chip->output_step = (int)(sample_rate * (double)(1 << FRAC_BITS) / (double)audio_sample_rate);	  chip->active_voices = data & 0x1f;	  	  if (LOG_COMMANDS && eslog)	    fprintf(eslog, "active voices=%d, sample_rate=%d, output_step=%08x\n", chip->active_voices, (int)sample_rate, chip->output_step);      }      break;          case 0x0e:	/* IRQV - read only */      break;          case 0x0f:	/* PAGE */	chip->current_page = data & 0x7f;      break;    }}INLINE void es5505_reg_write_high(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset, UINT16 data, UINT16 mem_mask){  //fprintf(stderr,"reg_write_high %x\n",offset);  switch (offset)    {    case 0x00:	/* CR */	  voice->control &= ~(CONTROL_STOPMASK | CONTROL_BS0 | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ);	  voice->control |= (data & (CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ)) |	    ((data << 12) & CONTROL_BS0);	  voice->control &= ~(CONTROL_CA0 | CONTROL_CA1 | CONTROL_LPMASK);	  voice->control |= ((data >> 2) & CONTROL_LPMASK) |	    ((data << 2) & (CONTROL_CA0 | CONTROL_CA1));      update_irq_state(chip);      break;          case 0x01:	/* O4(n-1) */	voice->o4n1 = (voice->o4n1 & ~0x00ff) | (data & 0x00ff);	voice->o4n1 = (INT16)((voice->o4n1 & ~0xff00) | (data & 0xff00));      break;          case 0x02:	/* O3(n-1) */	voice->o3n1 = (voice->o3n1 & ~0x00ff) | (data & 0x00ff);	voice->o3n1 = (INT16)((voice->o3n1 & ~0xff00) | (data & 0xff00));      break;          case 0x03:	/* O3(n-2) */	voice->o3n2 = (voice->o3n2 & ~0x00ff) | (data & 0x00ff);	voice->o3n2 = (INT16)((voice->o3n2 & ~0xff00) | (data & 0xff00));      break;          case 0x04:	/* O2(n-1) */	voice->o2n1 = (voice->o2n1 & ~0x00ff) | (data & 0x00ff);	voice->o2n1 = (INT16)((voice->o2n1 & ~0xff00) | (data & 0xff00));      break;          case 0x05:	/* O2(n-2) */	voice->o2n2 = (voice->o2n2 & ~0x00ff) | (data & 0x00ff);	voice->o2n2 = (INT16)((voice->o2n2 & ~0xff00) | (data & 0xff00));      break;          case 0x06:	/* O1(n-1) */	voice->o1n1 = (voice->o1n1 & ~0x00ff) | (data & 0x00ff);	voice->o1n1 = (INT16)((voice->o1n1 & ~0xff00) | (data & 0xff00));      break;          case 0x07:    case 0x08:    case 0x09:    case 0x0a:    case 0x0b:    case 0x0c:	/* unused */      break;          case 0x0d:	/* ACT */	{	  double sample_rate = chip->master_clock / (double)(16 * ((data & 0x1f) + 1));	  if (audio_sample_rate)	    chip->output_step = (int)(sample_rate * (double)(1 << FRAC_BITS) / (double)audio_sample_rate);	  chip->active_voices = data & 0x1f;	  	  if (LOG_COMMANDS && eslog)	    fprintf(eslog, "active voices=%d, sample_rate=%d, output_step=%08x\n", chip->active_voices, (int)sample_rate, chip->output_step);	}      break;          case 0x0e:	/* IRQV - read only */      break;          case 0x0f:	/* PAGE */	chip->current_page = data & 0x7f;      break;    }}INLINE void es5505_reg_write_test(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset, UINT16 data, UINT16 mem_mask){  //fprintf(stderr,"writetest offset %x data %x\n",offset,data);  switch (offset)    {    case 0x00:	/* CH0L */    case 0x01:	/* CH0R */    case 0x02:	/* CH1L */    case 0x03:	/* CH1R */    case 0x04:	/* CH2L */    case 0x05:	/* CH2R */    case 0x06:	/* CH3L */    case 0x07:	/* CH3R */      break;          case 0x08:	/* SERMODE */      chip->mode = data & 0x0007;      break;          case 0x09:	/* PAR */      break;          case 0x0d:	/* ACT */      if (ACCESSING_LSB)	{	  double sample_rate = chip->master_clock / (double)(16 * ((data & 0x1f) + 1));	  if (audio_sample_rate)	    chip->output_step = (int)(sample_rate * (double)(1 << FRAC_BITS) / (double)audio_sample_rate);	  chip->active_voices = data & 0x1f;	  	  if (LOG_COMMANDS && eslog)	    fprintf(eslog, "active voices=%d, sample_rate=%d, output_step=%08x\n", chip->active_voices, (int)sample_rate, chip->output_step);	}      break;          case 0x0e:	/* IRQV - read only */      break;          case 0x0f:	/* PAGE */      if (ACCESSING_LSB)	chip->current_page = data & 0x7f;      break;    }}static void es5505_reg_write(struct ES5506Chip *chip, offs_t offset, data16_t data, data16_t mem_mask){  struct ES5506Voice *voice = &chip->voice[chip->current_page & 0x1f];  //fprintf(stderr,"reg_write %x\n",offset);    //	logerror("%04x:ES5505 write %02x/%02x = %04x & %04x\n", cpu_getpreviouspc(), chip->current_page, offset, data, mem_mask ^ 0xffff);    /* force an update */  stream_update(chip->stream, 0);    /* switch off the page and register */  if (chip->current_page < 0x20)    es5505_reg_write_low(chip, voice, offset, data, mem_mask);  else if (chip->current_page < 0x40)    es5505_reg_write_high(chip, voice, offset, data, mem_mask);  else    es5505_reg_write_test(chip, voice, offset, data, mem_mask);}/**********************************************************************************************     es5505_reg_read -- read from the specified ES5505 register***********************************************************************************************/INLINE UINT16 es5505_reg_read_low(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset){  UINT16 result = 0;	  switch (offset)    {    case 0x00:	/* CR */      result = (voice->control & (CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ)) |	((voice->control & CONTROL_BS0) >> 12) |	((voice->control & CONTROL_LPMASK) << 2) |	((voice->control & (CONTROL_CA0 | CONTROL_CA1)) >> 2) |	0xf000;      voice->control &= ~CONTROL_IRQ;      update_irq_state(chip);      break;    case 0x01:	/* FC */      result = voice->freqcount >> 1;      break;	    case 0x02:	/* STRT (hi) */      result = voice->start >> 18;      break;	    case 0x03:	/* STRT (lo) */      result = voice->start >> 2;      break;	    case 0x04:	/* END (hi) */      result = voice->end >> 18;      break;	    case 0x05:	/* END (lo) */      result = voice->end >> 2;      break;	    case 0x06:	/* K2 */      result = voice->k2;      break;	    case 0x07:	/* K1 */      result = voice->k1;      break;	    case 0x08:	/* LVOL */      result = voice->lvol;      break;	    case 0x09:	/* RVOL */      result = voice->rvol;      break;	    case 0x0a:	/* ACC (hi) */      result = voice->accum >> 18;      break;	    case 0x0b:	/* ACC (lo) */      result = voice->accum >> 2;      break;	    case 0x0c:	/* unused */      break;	    case 0x0d:	/* ACT */      result = chip->active_voices;      break;			    case 0x0e:	/* IRQV */      result = chip->irqv;      break;	    case 0x0f:	/* PAGE */      result = chip->current_page;      break;    }  return result;}INLINE UINT16 es5505_reg_read_high(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset){  UINT16 result = 0;	  switch (offset)    {    case 0x00:	/* CR */      result = (voice->control & (CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ)) |	((voice->control & CONTROL_BS0) >> 12) |	((voice->control & CONTROL_LPMASK) << 2) |	((voice->control & (CONTROL_CA0 | CONTROL_CA1)) >> 2) |	0xf000;      voice->control &= ~CONTROL_IRQ;      update_irq_state(chip);      break;    case 0x01:	/* O4(n-1) */      result = voice->o4n1;      break;	    case 0x02:	/* O3(n-1) */      result = voice->o3n1;      break;	    case 0x03:	/* O3(n-2) */      result = voice->o3n2;      break;	    case 0x04:	/* O2(n-1) */      result = voice->o2n1;      break;	    case 0x05:	/* O2(n-2) */      result = voice->o2n2;      break;	    case 0x06:	/* O1(n-1) */      /* special case for the Taito F3 games: they set the accumulator on a stopped */      /* voice and assume the filters continue to process the data. They then read */      /* the O1(n-1) in order to extract raw data from the sound ROMs. Since we don't */      /* want to waste time filtering stopped channels, we just look for a read from */      /* this register on a stopped voice, and return the raw sample data at the */      /* accumulator */      if ((voice->control & CONTROL_STOPMASK) && chip->region_base[voice->control >> 14])	voice->o1n1 = chip->region_base[voice->control >> 14][voice->exbank + (voice->accum >> 11)];      result = voice->o1n1;      break;	    case 0x07:    case 0x08:    case 0x09:    case 0x0a:    case 0x0b:    case 0x0c:	/* unused */      break;	    case 0x0d:	/* ACT */      result = chip->active_voices;      break;			    case 0x0e:	/* IRQV */      result = chip->irqv;      break;	    case 0x0f:	/* PAGE */      result = chip->current_page;      break;    }  return result;}INLINE UINT16 es5505_reg_read_test(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset){  UINT16 result = 0;	  switch (offset)    {    case 0x00:	/* CH0L */    case 0x01:	/* CH0R */    case 0x02:	/* CH1L */    case 0x03:	/* CH1R */    case 0x04:	/* CH2L */    case 0x05:	/* CH2R */    case 0x06:	/* CH3L */    case 0x07:	/* CH3R */      break;			    case 0x08:	/* SERMODE */      result = chip->mode;      break;			    case 0x09:	/* PAR */      if (chip->port_read)	result = (*chip->port_read)();      break;	    case 0x0f:	/* PAGE */      result = chip->current_page;      break;    }  return result;}static data16_t es5505_reg_read(struct ES5506Chip *chip, offs_t offset){  struct ES5506Voice *voice = &chip->voice[chip->current_page & 0x1f];  data16_t result = 0;  if (LOG_COMMANDS && eslog)    fprintf(eslog, "read from %02x/%02x -> ", chip->current_page, offset);	/* force an update */  stream_update(chip->stream, 0);	  /* switch off the page and register */  if (chip->current_page < 0x20)    result = es5505_reg_read_low(chip, voice, offset);  else if (chip->current_page < 0x40)    result = es5505_reg_read_high(chip, voice, offset);  else    result = es5505_reg_read_test(chip, voice, offset);	  if (LOG_COMMANDS && eslog)    fprintf(eslog, "%04x (accum=%08x)\n", result, voice->accum);	/* return the high byte */  return result;}/**********************************************************************************************     ES5505_data_0_r/ES5505_data_1_r -- handle a read from the status register***********************************************************************************************/READ16_HANDLER( ES5505_data_0_r ){  int res;  offset &= 0x3f;  res=es5505_reg_read(&es5506[0], offset>>1);#ifdef DUMP  fprintf(stderr,"ess %x -> %x (pc:%6x)\n",offset>>1,res,s68000readPC());#endif  return res;}READ16_HANDLER( ES5505_data_1_r ){  offset &= 0x3f;  return es5505_reg_read(&es5506[1], offset>>1);}/**********************************************************************************************     ES5505_data_0_w/ES5505_data_1_w -- handle a write to the current register***********************************************************************************************/WRITE16_HANDLER( ES5505_data_0_ww ){  offset &= 0x3f;#ifdef DUMP  fprintf(stderr,"es5505_data_0_w %x,%x (%x)\n",offset>>1,data,s68000readPC());#endif  es5505_reg_write(&es5506[0], offset>>1, data, 0);}WRITE_HANDLER( ES5505_data_0_wb ){  int mem_mask;  offset &= 0x3f;#ifdef DUMP  fprintf(stderr,"es5505_data_0_w %x,%d\n",offset>>1,data);#endif  if (offset & 1) {    mem_mask = 0xff00;  } else {    mem_mask = 0x00ff;  }  fprintf(stderr,"mem_mask bad\n");  exit(1);  es5505_reg_write(&es5506[0], offset>>1, data, mem_mask);}WRITE16_HANDLER( ES5505_data_1_ww ){  offset &= 0x1f;  es5505_reg_write(&es5506[1], offset>>1, data, 0);}WRITE_HANDLER( ES5505_data_1_wb ){  int mem_mask;  offset &= 0x1f;  if (offset & 1) {    mem_mask = 0xff00;  } else {    mem_mask = 0x00ff;  }  es5505_reg_write(&es5506[1], offset>>1, data, mem_mask);}void ES5506_voice_bank_0_w(int voice, int bank){  es5506[0].voice[voice].control = CONTROL_STOPMASK;  es5506[0].voice[voice].exbank=bank;}void ES5506_voice_bank_1_w(int voice, int bank){  es5506[1].voice[voice].control = CONTROL_STOPMASK;  es5506[1].voice[voice].exbank=bank;}

⌨️ 快捷键说明

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