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

📄 es5506.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
📖 第 1 页 / 共 4 页
字号:
				fprintf(eslog, "voice %d, K2 ramp=%04x\n", chip->current_page & 0x1f, voice->k2ramp);			break;			case 0x48/8:	/* K1 */			voice->k1 = data & 0xffff;			if (LOG_COMMANDS && eslog)				fprintf(eslog, "voice %d, K1=%04x\n", chip->current_page & 0x1f, voice->k1);			break;			case 0x50/8:	/* K1RAMP */			voice->k1ramp = ((data & 0xff00) >> 8) | ((data & 0x0001) << 31);			if (LOG_COMMANDS && eslog)				fprintf(eslog, "voice %d, K1 ramp=%04x\n", chip->current_page & 0x1f, voice->k1ramp);			break;			case 0x58/8:	/* ACTV */		{			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 0x60/8:	/* MODE */			chip->mode = data & 0x1f;			break;			case 0x68/8:	/* PAR - read only */		case 0x70/8:	/* IRQV - read only */			break;			case 0x78/8:	/* PAGE */			chip->current_page = data & 0x7f;			break;	}}INLINE void es5506_reg_write_high(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset, UINT32 data){		  //fprintf(stderr,"ess_reg_write_high %x %d\n",offset,data);	switch (offset)	{		case 0x00/8:	/* CR */		  //if (!(voice->control & CONTROL_IRQ)){		    voice->control = data & 0xffff;		    update_irq_state(chip);		    //}		  break;					case 0x08/8:	/* START */			voice->start = data & 0x7ffff800;			if (!(voice->control & CONTROL_STOPMASK))			  fprintf(stderr,"got it start\n");			break;			case 0x10/8:	/* END */			voice->end = data & 0x7fffff80;			if (!(voice->control & CONTROL_STOPMASK))			  fprintf(stderr,"got it end\n");			break;			case 0x18/8:	/* ACCUM */			voice->accum = data & 0x7fffff80;			if (!(voice->control & CONTROL_STOPMASK))			  fprintf(stderr,"got it accum\n");			break;		case 0x20/8:	/* O4(n-1) */			voice->o4n1 = (INT32)(data << 14) >> 14;			if (LOG_COMMANDS && eslog)				fprintf(eslog, "voice %d, O4(n-1)=%05x\n", chip->current_page & 0x1f, voice->o4n1 & 0x3ffff);			break;			case 0x28/8:	/* O3(n-1) */			voice->o3n1 = (INT32)(data << 14) >> 14;			if (LOG_COMMANDS && eslog)				fprintf(eslog, "voice %d, O3(n-1)=%05x\n", chip->current_page & 0x1f, voice->o3n1 & 0x3ffff);			break;			case 0x30/8:	/* O3(n-2) */			voice->o3n2 = (INT32)(data << 14) >> 14;			if (LOG_COMMANDS && eslog)				fprintf(eslog, "voice %d, O3(n-2)=%05x\n", chip->current_page & 0x1f, voice->o3n2 & 0x3ffff);			break;			case 0x38/8:	/* O2(n-1) */			voice->o2n1 = (INT32)(data << 14) >> 14;			if (LOG_COMMANDS && eslog)				fprintf(eslog, "voice %d, O2(n-1)=%05x\n", chip->current_page & 0x1f, voice->o2n1 & 0x3ffff);			break;			case 0x40/8:	/* O2(n-2) */			voice->o2n2 = (INT32)(data << 14) >> 14;			if (LOG_COMMANDS && eslog)				fprintf(eslog, "voice %d, O2(n-2)=%05x\n", chip->current_page & 0x1f, voice->o2n2 & 0x3ffff);			break;			case 0x48/8:	/* O1(n-1) */			voice->o1n1 = (INT32)(data << 14) >> 14;			if (LOG_COMMANDS && eslog)				fprintf(eslog, "voice %d, O1(n-1)=%05x\n", chip->current_page & 0x1f, voice->o1n1 & 0x3ffff);			break;			case 0x50/8:	/* W_ST */			chip->wst = data & 0x7f;			break;			case 0x58/8:	/* W_END */			chip->wend = data & 0x7f;			break;			case 0x60/8:	/* LR_END */			chip->lrend = data & 0x7f;			break;			case 0x68/8:	/* PAR - read only */		case 0x70/8:	/* IRQV - read only */			break;			case 0x78/8:	/* PAGE */			chip->current_page = data & 0x7f;			break;	}}static void es5506_reg_write(struct ES5506Chip *chip, offs_t offset, data8_t data){	struct ES5506Voice *voice = &chip->voice[chip->current_page & 0x1f];	int shift = 8 * (offset & 3);	//fprintf(stderr,"ess_reg_write %x %d\n",offset,data);	/* accumulate the data */		chip->write_latch = (chip->write_latch & ~(0xff000000 >> shift)) | (data << (24 - shift));	/* wait for a write to complete */	if (shift != 24)		return;/*	logerror("%04x:ES5506 write %02x/%02x = %08x\n", cpu_getpreviouspc(), chip->current_page, offset / 4 * 8, chip->write_latch);*/	/* force an update */	stream_update(chip->stream, 0);		/* switch off the page and register */	if (chip->current_page < 0x20)		es5506_reg_write_low(chip, voice, offset / 4, chip->write_latch);	else if (chip->current_page < 0x40)		es5506_reg_write_high(chip, voice, offset / 4, chip->write_latch);	/* clear the write latch when done */	chip->write_latch = 0;}/**********************************************************************************************     es5506_reg_read -- read from the specified ES5506 register***********************************************************************************************/INLINE UINT32 es5506_reg_read_low(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset){	UINT32 result = 0;		switch (offset)	{		case 0x00/8:	/* CR */			result = voice->control;			voice->control &= ~CONTROL_IRQ;			update_irq_state(chip);			break;					case 0x08/8:	/* FC */			result = voice->freqcount;			break;			case 0x10/8:	/* LVOL */			result = voice->lvol;			break;			case 0x18/8:	/* LVRAMP */			result = voice->lvramp << 8;			break;			case 0x20/8:	/* RVOL */			result = voice->rvol;			break;			case 0x28/8:	/* RVRAMP */			result = voice->rvramp << 8;			break;			case 0x30/8:	/* ECOUNT */			result = voice->ecount;			break;			case 0x38/8:	/* K2 */			result = voice->k2;			break;			case 0x40/8:	/* K2RAMP */			result = (voice->k2ramp << 8) | (voice->k2ramp >> 31);			break;			case 0x48/8:	/* K1 */			result = voice->k1;			break;			case 0x50/8:	/* K1RAMP */			result = (voice->k1ramp << 8) | (voice->k1ramp >> 31);			break;			case 0x58/8:	/* ACTV */			result = chip->active_voices;			break;			case 0x60/8:	/* MODE */			result = chip->mode;			break;			case 0x68/8:	/* PAR */			if (chip->port_read)				result = (*chip->port_read)();			break;					case 0x70/8:	/* IRQV */			result = chip->irqv;			break;			case 0x78/8:	/* PAGE */			result = chip->current_page;			break;	}	return result;}INLINE UINT32 es5506_reg_read_high(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset){	UINT32 result = 0;		switch (offset)	{		case 0x00/8:	/* CR */			result = voice->control;			voice->control &= ~CONTROL_IRQ;			update_irq_state(chip);			break;					case 0x08/8:	/* START */			result = voice->start;			break;			case 0x10/8:	/* END */			result = voice->end;			break;			case 0x18/8:	/* ACCUM */			result = voice->accum;			break;			case 0x20/8:	/* O4(n-1) */			result = voice->o4n1 & 0x3ffff;			break;			case 0x28/8:	/* O3(n-1) */			result = voice->o3n1 & 0x3ffff;			break;			case 0x30/8:	/* O3(n-2) */			result = voice->o3n2 & 0x3ffff;			break;			case 0x38/8:	/* O2(n-1) */			result = voice->o2n1 & 0x3ffff;			break;			case 0x40/8:	/* O2(n-2) */			result = voice->o2n2 & 0x3ffff;			break;			case 0x48/8:	/* O1(n-1) */			result = voice->o1n1 & 0x3ffff;			break;			case 0x50/8:	/* W_ST */			result = chip->wst;			break;			case 0x58/8:	/* W_END */			result = chip->wend;			break;			case 0x60/8:	/* LR_END */			result = chip->lrend;			break;			case 0x68/8:	/* PAR */			if (chip->port_read)				result = (*chip->port_read)();			break;					case 0x70/8:	/* IRQV */			result = chip->irqv;			break;			case 0x78/8:	/* PAGE */			result = chip->current_page;			break;	}	return result;}static data8_t es5506_reg_read(struct ES5506Chip *chip, offs_t offset){	struct ES5506Voice *voice = &chip->voice[chip->current_page & 0x1f];	int shift = 8 * (offset & 3);	/* only read on offset 0 */	if (shift != 0)		return chip->read_latch >> (24 - shift);	if (LOG_COMMANDS && eslog)		fprintf(eslog, "read from %02x/%02x -> ", chip->current_page, offset / 4 * 8);	/* force an update */	stream_update(chip->stream, 0);		/* switch off the page and register */	if (chip->current_page < 0x20)		chip->read_latch = es5506_reg_read_low(chip, voice, offset / 4);	else if (chip->current_page < 0x40)		chip->read_latch = es5506_reg_read_high(chip, voice, offset / 4);		if (LOG_COMMANDS && eslog)		fprintf(eslog, "%08x\n", chip->read_latch);	/* return the high byte */	return chip->read_latch >> 24;}/**********************************************************************************************     ES5506_data_0_r/ES5506_data_1_r -- handle a read from the status register***********************************************************************************************/READ_HANDLER( ES5506_data_0_r ){  int res;  offset&=0x3f;  res = es5506_reg_read(&es5506[0], offset>>1);#ifdef DUMP  fprintf(stderr,"ess %x -> %x (pc:%6x)\n",offset>>1,res,s68000readPC());#endif    return res;}READ_HANDLER( ES5506_data_1_r ){  offset&=0x3f;  return es5506_reg_read(&es5506[1], offset>>1);}/**********************************************************************************************     ES5506_data_0_w/ES5506_data_1_w -- handle a write to the current register***********************************************************************************************/WRITE_HANDLER( ES5506_data_0_w ){  offset&=0x3f;  // How fascinating : these functions do not care about mem_mask ???!  es5506_reg_write(&es5506[0], offset>>1, data);}WRITE_HANDLER( ES5506_data_1_w ){  offset&=0x3f;  es5506_reg_write(&es5506[1], offset>>1, data);}/**********************************************************************************************     ES5505_sh_start -- start emulation of the ES5505***********************************************************************************************/int ES5505_sh_start(const struct ES5505interface *intf){	struct ES5506interface es5506intf;	memset(&es5506intf, 0, sizeof(es5506intf));		es5506intf.num = intf->num;	memcpy(es5506intf.baseclock, intf->baseclock, sizeof(es5506intf.baseclock));	memcpy(es5506intf.region0, intf->region0, sizeof(es5506intf.region0));	memcpy(es5506intf.region1, intf->region1, sizeof(es5506intf.region1));	memcpy(es5506intf.mixing_level, intf->mixing_level, sizeof(es5506intf.mixing_level));	memcpy(es5506intf.irq_callback, intf->irq_callback, sizeof(es5506intf.irq_callback));	memcpy(es5506intf.read_port, intf->read_port, sizeof(es5506intf.read_port));	return ES5506_sh_start(&es5506intf);}/**********************************************************************************************     ES5505_sh_stop -- stop emulation of the ES5506***********************************************************************************************/void ES5505_sh_stop(void){	ES5506_sh_stop();} /**********************************************************************************************     es5505_reg_write -- handle a write to the selected ES5505 register***********************************************************************************************/INLINE void es5505_reg_write_low(struct ES5506Chip *chip, struct ES5506Voice *voice, offs_t offset, UINT16 data, UINT16 mem_mask){  //fprintf(stderr,"reg_write_low %x %d\n",offset,data);  switch (offset)    {    case 0x00:	/* CR */#if 1      // Notice : normally ACCESSING_LSB and MSB should be ALWAYS true.      // I am not totally certain, so I leave the code this way for now      //if (!(voice->control & CONTROL_IRQ)){      //fprintf(stderr,"voice %x old status %x... ",voice,voice->control);      voice->control &= ~(CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_DIR);      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);      //fprintf(stderr,"new status %x\n",voice->control);      //} else      //fprintf(stderr,"reject %x\n",voice->control);#else			if (ACCESSING_LSB)			{				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);			}			if (ACCESSING_MSB)			{				voice->control &= ~(CONTROL_CA0 | CONTROL_CA1 | CONTROL_LPMASK);				voice->control |= ((data >> 2) & CONTROL_LPMASK) |								  ((data << 2) & (CONTROL_CA0 | CONTROL_CA1));			}#endif            break;          case 0x01:	/* FC */	voice->freqcount = (voice->freqcount & ~0x001fe) | ((data & 0x00ff) << 1);	voice->freqcount = (voice->freqcount & ~0x1fe00) | ((data & 0xff00) << 1);      break;          case 0x02:	/* STRT (hi) */	voice->start = (voice->start & ~0x03fc0000) | ((data & 0x00ff) << 18);	voice->start = (voice->start & ~0x7c000000) | ((data & 0x1f00) << 18);	/* generate interrupt */	break;          case 0x03:	/* STRT (lo) */	voice->start = (voice->start & ~0x00000380) | ((data & 0x00e0) << 2);	voice->start = (voice->start & ~0x0003fc00) | ((data & 0xff00) << 2);	/* generate interrupt */      break;	    case 0x04:	/* END (hi) */	voice->end = (voice->end & ~0x03fc0000) | ((data & 0x00ff) << 18);	voice->end = (voice->end & ~0x7c000000) | ((data & 0x1f00) << 18);	voice->control |= CONTROL_STOP0;	/* generate interrupt */      break;          case 0x05:	/* END (lo) */	voice->end = (voice->end & ~0x00000380) | ((data & 0x00e0) << 2);	voice->end = (voice->end & ~0x0003fc00) | ((data & 0xff00) << 2);	voice->control |= CONTROL_STOP0;      /* generate interrupt */	//if ((voice->control&3)==0 && voice->accum < voice->start){	//voice->control |= (CONTROL_IRQ | CONTROL_STOPMASK);

⌨️ 快捷键说明

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