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; } }