qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v3 24/25] ym2608intf: YM2608 core forked from MAME 0


From: TAKEDA, toshiya
Subject: [Qemu-devel] [PATCH v3 24/25] ym2608intf: YM2608 core forked from MAME 0.59
Date: Thu, 29 Oct 2009 01:50:45 +0900

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 ****************/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]