www.pudn.com > ngcd080s.zip > ym2610.c


/************************************** 
***    YM2610 emulation routines    *** 
***---------------------------------***. 
*** Information from MAME project's *** 
***   fm.c by Tatsuyuki Satoh and   *** 
***        Hiromitsu Shioya         *** 
**************************************/ 
 
//-- Include Files ---------------------------------------------------------- 
#include  
#include  
#include  
#include "../sound/stream.h" 
#include "../ym2610/adpcm.h" 
#include "../gui/gui.h" 
 
//-- Defines ---------------------------------------------------------------- 
//#define _DEBUG_ 
#define	MAX_VOICES	7 
#define NUM_BUFFERS	3 
 
//-- Variables -------------------------------------------------------------- 
AUDIOINFO	audio_info; 
char		audio_error[128]; 
int			audio_freq; 
int			sound_vol; 
int			address_register0 = 0; 
int			address_register1 = 0; 
int			port0state = 0; 
int			port1state = -1; 
int			port0shift = 8; 
int			port1shift = 8; 
int			sound_device = -1; 
 
#ifdef _DEBUG_ 
FILE	*logfile; 
#endif 
 
//-- Exported Functions ----------------------------------------------------- 
int		YM2610Init(void); 
void	YM2610Write(int Register, int Value); 
int		YM2610Read(int Register); 
 
//--------------------------------------------------------------------------- 
int	YM2610Init(void) 
{ 
	int	rc; 
	int	i; 
	 
	if ((rc = AInitialize()) != AUDIO_ERROR_NONE) { 
		AGetErrorText(rc, audio_error, sizeof(audio_error) - 1); 
		neo_alert1("Audio Error", audio_error, "Sound disabled.", NULL, "&OK", 'o'); 
		sound_device = 0; 
		return 0; 
	}		 
 
	if (sound_device == -1) 
	{ 
		if (APingAudio(&sound_device) != AUDIO_ERROR_NONE) 
		{ 
			neo_alert1("Audio Error", "no audio device found.", "Sound disabled.", NULL, "&OK", 'o'); 
			sound_device = 0; 
		} 
    } 
	 
	audio_info.nDeviceId = sound_device; 
	audio_info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO | AUDIO_FORMAT_FILTER; 
	audio_info.nSampleRate = 44100; 
	if ((rc = AOpenAudio(&audio_info)) != AUDIO_ERROR_NONE) { 
		AGetErrorText(rc, audio_error, sizeof(audio_error) - 1); 
		return 0; 
	} 
	 
	audio_freq = audio_info.nSampleRate; 
	 
	if ((rc = AOpenVoices(MAX_VOICES)) != AUDIO_ERROR_NONE) { 
		ACloseAudio(); 
		AGetErrorText(rc, audio_error, sizeof(audio_error) - 1); 
		neo_alert1("Audio Error", audio_error, "Sound disabled.", NULL, "&OK", 'o'); 
		sound_device = 0; 
		return 0; 
	} 
 
	adpcm_init(); 
	stream_init(); 
	 
	for(i=0;i<7;i++) 
		adpcm_ch_init(&adpcm_ch[i]); 
		 
	adpcm_ch[0].ch_val = 1; 
	adpcm_ch[1].ch_val = 2; 
	adpcm_ch[2].ch_val = 4; 
	adpcm_ch[3].ch_val = 8; 
	adpcm_ch[4].ch_val = 16; 
	adpcm_ch[5].ch_val = 32; 
	adpcm_ch[6].ch_val = 128; 
	 
	return 1; 
} 
 
//--------------------------------------------------------------------------- 
void	YM2610Shutdown(void) 
{ 
	stream_kill_all(); 
	ACloseVoices(); 
	ACloseAudio(); 
} 
 
//--------------------------------------------------------------------------- 
int	YM2610Read(int Register) 
{ 
	switch(Register&3) 
	{ 
	case	0: 
		#ifdef _DEBUG_ 
		logfile = fopen("c:\\tmp\\adpcm.logfile", "at"); 
		fprintf(logfile, "YM2610Read: %d %02x\n", Register, 0); 
		fclose(logfile); 
		#endif 
 
		return 0;//status & 0x83; 
				 
	case	1: 
		if (address_register0 < 0x10) 
//			return SSGRead(); 
			return 0x0; 
		 
		if (address_register0 == 0xff) 
		{ 
		#ifdef _DEBUG_ 
		logfile = fopen("c:\\tmp\\adpcm.logfile", "at"); 
		fprintf(logfile, "YM2610Read: %d %02x\n", Register, 0x1); 
		fclose(logfile); 
		#endif 
			return 0x1; 
		} 
 
	case	2: 
		#ifdef _DEBUG_ 
		logfile = fopen("c:\\tmp\\adpcm.logfile", "at"); 
		fprintf(logfile, "YM2610Read: %d %02x\n", Register, (adpcm_status & adpcm_statusmask)); 
		fclose(logfile); 
		#endif 
		 
		return (adpcm_status & adpcm_statusmask); 
	} 
	 
	return 0; 
} 
 
//--------------------------------------------------------------------------- 
void	YM2610Write(int Register, int Value) 
{ 
	#ifdef _DEBUG_ 
	logfile = fopen("c:\\tmp\\adpcm.logfile", "at"); 
	fprintf(logfile, "YM2610Write: %d %02x\n", Register, Value); 
	fclose(logfile); 
	#endif 
 
	switch(Register&3) 
	{ 
	case	0: 
		address_register0 = Value & 0xFF; 
		break; 
	 
	case	1: 
		switch(address_register0 & 0xF0) 
		{ 
//		case	0: 
//			SSGWrite(); 
//			break; 
 
		case	0x10: 
			if (address_register0 == 0x1C) 
			{ 
				adpcm_statusmask = ~Value; 
				adpcm_status &= adpcm_statusmask; 
			} 
			else 
				adpcmb_write(address_register0 & 0x0F, Value); 
				 
			break; 
		 
//		case	0x20: 
//			OPNWriteMode(); 
//			break; 
 
//		default: 
//			OPNWriteReg(address_register0, Value); 
//			break; 
		} 
		break; 
 
	case	2: 
		address_register1 = Value & 0xFF; 
		break; 
	 
	case	3: 
		if (address_register1 < 0x30) 
			adpcma_write(address_register1, Value); 
//		else 
//			OPNWriteReg(address_register1 | 0x100, Value); 
		break; 
	} 
}