diff --git a/qemu/hw/ym2608intf.c b/qemu/hw/ym2608intf.c new file mode 100644 index 0000000..35e1064 --- /dev/null +++ b/qemu/hw/ym2608intf.c @@ -0,0 +1,234 @@ +/* don't support sampling rythm sound yet */ +//#define YM2608_USE_SAMPLES +/*************************************************************************** + + 2608intf.c + + The YM2608 emulator supports up to 2 chips. + Each chip has the following connections: + - Status Read / Control Write A + - Port Read / Data Write A + - Control Write B + - Data Write B + +***************************************************************************/ + +/* This version of 2608intf.c is a fork of the MAME 0.59 one, relicensed under the LGPL. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "hw.h" +#include "ay8910.h" +#include "ym2608intf.h" +#include "fm.h" + +static signed short *rhythm_buf; + +/* Global Interface holder */ +static const struct YM2608interface *intf; + +#ifdef YM2608_USE_SAMPLES +static const char *ym2608_pDrumNames[] = +{ + "2608_BD.wav", + "2608_SD.wav", + "2608_TOP.wav", + "2608_HH.wav", + "2608_TOM.wav", + "2608_RIM.wav", + 0 +}; + +/* definitions in commmon.c */ +struct GameSample +{ + int length; + int smpfreq; + int resolution; + signed char data[1]; /* extendable */ +}; +struct GameSamples +{ + int total; /* total number of samples */ + struct GameSample *sample[1]; /* extendable */ +}; +struct GameSamples *readsamples(const char **samplenames,const char *basename) +{ + return 0; +} +#define freesamples(samps) +#endif + +/*------------------------- YM2608 -------------------------------*/ +/* IRQ Handler */ +static void IRQHandler(int n,int irq) +{ + if(intf->handler[n]) intf->handler[n](irq); +} + +/* TimerHandler from fm.c */ +static void TimerHandler(int n,int c,int count,int clock) +{ + if(intf->timer_handler[n]) intf->timer_handler[n](c, count); +} + +/* update request from fm.c */ +void YM2608UpdateRequest(int chip) +{ + if(intf->update_handler[chip]) intf->update_handler[chip](); +} + +int YM2608_sh_start(const struct MachineSound *msound, int rate) +{ + int i; + void *pcmbufa[YM2608_NUMBUF]; + int pcmsizea[YM2608_NUMBUF]; + int rhythm_pos[6+1]; +#ifdef YM2608_USE_SAMPLES + int j; + struct GameSamples *psSamples; + int total_size,r_offset,s_size; +#endif + + intf = msound->sound_interface; + if( intf->num > MAX_2608 ) return 1; + + if (AY8910_sh_start_ym(msound, rate)) return 1; + + /* stream system initialize */ + for (i = 0;i < intf->num;i++) + { + /* setup adpcm buffers */ + pcmbufa[i] = (void *)intf->pcmram[i]; + pcmsizea[i] = intf->pcmram_size[i]; + } + + /* rythm rom build */ + rhythm_buf = 0; +#ifdef YM2608_USE_SAMPLES + psSamples = readsamples(ym2608_pDrumNames,"ym2608"); + if( psSamples ) + { + /* calcrate total data size */ + total_size = 0; + for( i=0;i<6;i++) + { + s_size = psSamples->sample[i]->length; + total_size += s_size ? s_size : 1; + } + /* aloocate rythm data */ + rhythm_buf = malloc(total_size * sizeof(signed short)); + if( rhythm_buf==0 ) return 0; + + r_offset = 0; + /* merge sampling data */ + for(i=0;i<6;i++) + { + /* set start point */ + rhythm_pos[i] = r_offset*2; + /* copy sample data */ + s_size = psSamples->sample[i]->length; + if(s_size && psSamples->sample[i]->data) + { + if( psSamples->sample[i]->resolution==16 ) + { + signed short *s_ptr = (signed short *)psSamples->sample[i]->data; + for(j=0;j<s_size;j++) rhythm_buf[r_offset++] = *s_ptr++; + }else{ + signed char *s_ptr = (signed char *)psSamples->sample[i]->data; + for(j=0;j<s_size;j++) rhythm_buf[r_offset++] = (*s_ptr++)*0x0101; + } + }else rhythm_buf[r_offset++] = 0; + /* set end point */ + rhythm_pos[i+1] = r_offset*2; + } + freesamples( psSamples ); + }else + { +#endif + /* aloocate rythm data */ + rhythm_buf = malloc(6 * sizeof(signed short)); + if( rhythm_buf==0 ) return 0; + for(i=0;i<6;i++) + { + /* set start point */ + rhythm_pos[i] = i*2; + rhythm_buf[i] = 0; + /* set end point */ + rhythm_pos[i+1] = (i+1)*2; + } +#ifdef YM2608_USE_SAMPLES + } +#endif + + /**** initialize YM2608 ****/ + if (YM2608Init(intf->num,intf->baseclock,rate, + pcmbufa,pcmsizea,rhythm_buf,rhythm_pos, + TimerHandler,IRQHandler) == 0) + return 0; + + /* error */ + return 1; +} + +/************************************************/ +/* Sound Hardware Stop */ +/************************************************/ +void YM2608_sh_stop(void) +{ + YM2608Shutdown(); + if( rhythm_buf ) free(rhythm_buf); + rhythm_buf = 0; + AY8910_sh_stop_ym(); +} +/* reset */ +void YM2608_sh_reset(void) +{ + int i; + + for (i = 0;i < intf->num;i++) + YM2608ResetChip(i); +} + +void YM2608_sh_postload(void) +{ + int i; + + for (i = 0;i < intf->num;i++) { + YM2608_postload(i); + } +} + +void YM2608_sh_save_state(QEMUFile* f) +{ + int i; + + for (i = 0;i < intf->num;i++) { + YM2608_save_state(f, i); + } +} + +int YM2608_sh_load_state(QEMUFile* f) +{ + int i, ret = 0; + + for (i = 0;i < intf->num;i++) { + ret |= YM2608_load_state(f, i); + } + return ret; +} + +/**************** end of file ****************/ + diff --git a/qemu/hw/ym2608intf.h b/qemu/hw/ym2608intf.h new file mode 100644 index 0000000..ca83102 --- /dev/null +++ b/qemu/hw/ym2608intf.h @@ -0,0 +1,47 @@ +#ifndef __2608INTF_H__ +#define __2608INTF_H__ + +#include "hw.h" +#include "fm.h" +#include "ay8910.h" +#include "fm_def.h" + +#define MAX_2608 (2) + +#ifndef VOL_YM3012 +/* #define YM3014_VOL(Vol,Pan) VOL_YM3012((Vol)/2,Pan,(Vol)/2,Pan) */ +#define YM3012_VOL(LVol,LPan,RVol,RPan) (MIXER(LVol,LPan)|(MIXER(RVol,RPan) << 16)) +#endif + +struct YM2608interface{ + int num; /* total number of 8910 in the machine */ + int baseclock; + mem_read_handler portAread[MAX_8910]; + mem_read_handler portBread[MAX_8910]; + mem_write_handler portAwrite[MAX_8910]; + mem_write_handler portBwrite[MAX_8910]; + void ( *handler[MAX_8910] )( int irq ); /* IRQ handler for the YM2608 */ + void ( *timer_handler[MAX_8910] )( int c, int count ); + void ( *update_handler[MAX_8910] )( void ); + unsigned char *pcmram[MAX_2608]; + int pcmram_size[MAX_2608]; +}; + +/************************************************/ +/* Sound Hardware Start */ +/************************************************/ +int YM2608_sh_start(const struct MachineSound *msound, int rate); + +/************************************************/ +/* Sound Hardware Stop */ +/************************************************/ +void YM2608_sh_stop(void); + +void YM2608_sh_reset(void); + +void YM2608_sh_postload(void); +void YM2608_sh_save_state(QEMUFile* f); +int YM2608_sh_load_state(QEMUFile* f); + +#endif +/**************** end of file ****************/