summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-30 19:10:14 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-30 19:10:14 +0200
commitbf662a727b11017266c2a85bc1308a730076bf3e (patch)
tree48efaa8a8f4e013fadcce38c29833219e7303a7a
parenta1fce239dce0c2bdbf408d0ea19dd5a96bb328cf (diff)
ao plugin: qsound emu reentrant
-rw-r--r--plugins/ao/eng_qsf/eng_qsf.c18
-rw-r--r--plugins/ao/eng_qsf/qsound.c204
-rw-r--r--plugins/ao/eng_qsf/qsound.h106
3 files changed, 168 insertions, 160 deletions
diff --git a/plugins/ao/eng_qsf/eng_qsf.c b/plugins/ao/eng_qsf/eng_qsf.c
index 2cd2ce6e..95c811ad 100644
--- a/plugins/ao/eng_qsf/eng_qsf.c
+++ b/plugins/ao/eng_qsf/eng_qsf.c
@@ -83,6 +83,7 @@ typedef struct {
char RAM[0x1000], RAM2[0x1000];
int32 cur_bank;
z80_state_t *z80;
+ qsound_state_t *qs;
} qsf_synth_t;
static struct QSound_interface qsintf =
@@ -283,7 +284,7 @@ void *qsf_start(const char *path, uint8 *buffer, uint32 length)
z80_set_irq_callback(s->z80, qsf_irq_cb);
}
qsintf.sample_rom = s->QSamples;
- qsound_sh_start(&qsintf);
+ s->qs = qsound_sh_start(&qsintf);
return s;
}
@@ -319,7 +320,7 @@ int32 qsf_gen(qsf_synth_t *s, int16 *buffer, uint32 samples)
z80_execute(s->z80, (8000000/44100)*tickinc);
stereo[0] = &output[opos];
stereo[1] = &output2[opos];
- qsound_update(0, stereo, tickinc);
+ qsound_update(s->qs, 0, stereo, tickinc);
opos += tickinc;
samples_to_next_tick -= tickinc;
@@ -337,7 +338,7 @@ int32 qsf_gen(qsf_synth_t *s, int16 *buffer, uint32 samples)
z80_execute(s->z80, (8000000/44100)*(samples-opos));
stereo[0] = &output[opos];
stereo[1] = &output2[opos];
- qsound_update(0, stereo, (samples-opos));
+ qsound_update(s->qs, 0, stereo, (samples-opos));
samples_to_next_tick -= (samples-opos);
@@ -365,6 +366,9 @@ int32 qsf_stop(void *handle)
if (s->z80) {
z80_free (s->z80);
}
+ if (s->qs) {
+ qsound_sh_stop (s->qs);
+ }
free(s);
return AO_SUCCESS;
@@ -430,7 +434,7 @@ uint8 qsf_memory_read(qsf_synth_t *s, uint16 addr)
}
else if (addr == 0xd007)
{
- return qsound_status_r();
+ return qsound_status_r(s->qs);
}
else if (addr >= 0xf000)
{
@@ -469,17 +473,17 @@ void qsf_memory_write(qsf_synth_t *s, uint16 addr, uint8 byte)
}
else if (addr == 0xd000)
{
- qsound_data_h_w(byte);
+ qsound_data_h_w(s->qs, byte);
return;
}
else if (addr == 0xd001)
{
- qsound_data_l_w(byte);
+ qsound_data_l_w(s->qs, byte);
return;
}
else if (addr == 0xd002)
{
- qsound_cmd_w(byte);
+ qsound_cmd_w(s->qs, byte);
return;
}
else if (addr == 0xd003)
diff --git a/plugins/ao/eng_qsf/qsound.c b/plugins/ao/eng_qsf/qsound.c
index 10b500b4..7554cc73 100644
--- a/plugins/ao/eng_qsf/qsound.c
+++ b/plugins/ao/eng_qsf/qsound.c
@@ -35,122 +35,36 @@
#include "cpuintrf.h"
#include "qsound.h"
-/*
-Two Q sound drivers:
-DRIVER1 Based on the Amuse source
-DRIVER2 Miguel Angel Horna (mahorna@teleline.es)
-*/
-#define QSOUND_DRIVER1 1
-/*
-I don't know whether this system uses 8 bit or 16 bit samples.
-If it uses 16 bit samples then the sample ROM loading macros need
-to be modified to work with non-intel machines.
-*/
-#define QSOUND_8BIT_SAMPLES 1
-
-/*
-Debug defines
-*/
-#define LOG_WAVE 0
-#define LOG_QSOUND 0
-
-/* Typedefs & defines */
-
-#define QSOUND_DRIVER2 !QSOUND_DRIVER1
-
-#if QSOUND_8BIT_SAMPLES
-/* 8 bit source ROM samples */
-typedef signed char QSOUND_SRC_SAMPLE;
-#define LENGTH_DIV 1
-#else
-/* 8 bit source ROM samples */
-typedef signed short QSOUND_SRC_SAMPLE;
-#define LENGTH_DIV 2
-#endif
-
-#define QSOUND_CLOCKDIV 166 /* Clock divider */
-#define QSOUND_CHANNELS 16
-typedef INT16 QSOUND_SAMPLE;
-
-struct QSOUND_CHANNEL
-{
- int bank; /* bank (x16) */
- int address; /* start address */
- int pitch; /* pitch */
- int reg3; /* unknown (always 0x8000) */
- int loop; /* loop address */
- int end; /* end address */
- int vol; /* master volume */
- int pan; /* Pan value */
- int reg9; /* unknown */
-
- /* Work variables */
- int key; /* Key on / key off */
-
-#if QSOUND_DRIVER1
- int lvol; /* left volume */
- int rvol; /* right volume */
- int lastdt; /* last sample value */
- int offset; /* current offset counter */
-#else
- QSOUND_SRC_SAMPLE *buffer;
- int factor; /*step factor (fixed point 8-bit)*/
- int mixl,mixr; /*mixing factor (fixed point)*/
- int cursor; /*current sample position (fixed point)*/
- int lpos; /*last cursor pos*/
- int lastsaml; /*last left sample (to avoid any calculation)*/
- int lastsamr; /*last right sample*/
-#endif
-};
-
-
-/* Private variables */
-static struct QSound_interface *intf; /* Interface */
-static int qsound_stream; /* Audio stream */
-static struct QSOUND_CHANNEL qsound_channel[QSOUND_CHANNELS];
-static int qsound_data; /* register latch data */
-QSOUND_SRC_SAMPLE *qsound_sample_rom; /* Q sound sample ROM */
-
-#if QSOUND_DRIVER1
-static int qsound_pan_table[33]; /* Pan volume table */
-static float qsound_frq_ratio; /* Frequency ratio */
-#endif
-
-#if LOG_WAVE
-static FILE *fpRawDataL;
-static FILE *fpRawDataR;
-#endif
-
-/* Function prototypes */
-void qsound_update( int num, INT16 **buffer, int length );
-void qsound_set_command(int data, int value);
-
+#if 0
#if QSOUND_DRIVER2
void setchannel(int channel,signed short *buffer,int length,int vol,int pan);
void setchloop(int channel,int loops,int loope);
void stopchan(int channel);
void calcula_mix(int channel);
#endif
+#endif
-int qsound_sh_start( struct QSound_interface *qsintf )
+qsound_state_t *qsound_sh_start( struct QSound_interface *qsintf )
{
- int i;
+ qsound_state_t *qs = malloc (sizeof (qsound_state_t));
+ memset (qs, 0, sizeof (qsound_state_t));
+ memcpy (&qs->intf, qsintf, sizeof (struct QSound_interface));
- intf = qsintf;
+ int i;
- qsound_sample_rom = (QSOUND_SRC_SAMPLE *)intf->sample_rom;
+ qs->qsound_sample_rom = (QSOUND_SRC_SAMPLE *)qs->intf.sample_rom;
- memset(qsound_channel, 0, sizeof(qsound_channel));
+ memset(qs->qsound_channel, 0, sizeof(qs->qsound_channel));
#if QSOUND_DRIVER1
- qsound_frq_ratio = ((float)intf->clock / (float)QSOUND_CLOCKDIV) /
+ qs->qsound_frq_ratio = ((float)qs->intf.clock / (float)QSOUND_CLOCKDIV) /
(float) 44100;
- qsound_frq_ratio *= 16.0;
+ qs->qsound_frq_ratio *= 16.0;
/* Create pan table */
for (i=0; i<33; i++)
{
- qsound_pan_table[i]=(int)((256/sqrt(32)) * sqrt(i));
+ qs->qsound_pan_table[i]=(int)((256/sqrt(32)) * sqrt(i));
}
#else
i=0;
@@ -159,7 +73,7 @@ int qsound_sh_start( struct QSound_interface *qsintf )
#if LOG_QSOUND
logerror("Pan table\n");
for (i=0; i<33; i++)
- logerror("%02x ", qsound_pan_table[i]);
+ logerror("%02x ", qs->qsound_pan_table[i]);
#endif
#if 0
{
@@ -184,18 +98,18 @@ int qsound_sh_start( struct QSound_interface *qsintf )
}
#endif
#if LOG_WAVE
- fpRawDataR=fopen("qsoundr.raw", "w+b");
- fpRawDataL=fopen("qsoundl.raw", "w+b");
- if (!fpRawDataR || !fpRawDataL)
+ qs->fpRawDataR=fopen("qsoundr.raw", "w+b");
+ qs->fpRawDataL=fopen("qsoundl.raw", "w+b");
+ if (!qs->fpRawDataR || !qs->fpRawDataL)
{
- return 1;
+ return NULL;
}
#endif
- return 0;
+ return qs;
}
-void qsound_sh_stop (void)
+void qsound_sh_stop (qsound_state_t *qs)
{
#if LOG_WAVE
if (fpRawDataR)
@@ -209,29 +123,29 @@ void qsound_sh_stop (void)
#endif
}
-void qsound_data_h_w(int data)
+void qsound_data_h_w(qsound_state_t *qs, int data)
{
- qsound_data=(qsound_data&0xff)|(data<<8);
+ qs->qsound_data=(qs->qsound_data&0xff)|(data<<8);
}
-void qsound_data_l_w(int data)
+void qsound_data_l_w(qsound_state_t *qs, int data)
{
- qsound_data=(qsound_data&0xff00)|data;
+ qs->qsound_data=(qs->qsound_data&0xff00)|data;
}
-void qsound_cmd_w(int data)
+void qsound_cmd_w(qsound_state_t *qs, int data)
{
-// printf("QS: cmd %x, data %x\n", data, qsound_data);
- qsound_set_command(data, qsound_data);
+// printf("QS: cmd %x, data %x\n", data, qs->qsound_data);
+ qsound_set_command(qs, data, qs->qsound_data);
}
-int qsound_status_r(void)
+int qsound_status_r(qsound_state_t *qs)
{
/* Port ready bit (0x80 if ready) */
return 0x80;
}
-void qsound_set_command(int data, int value)
+void qsound_set_command(qsound_state_t *qs, int data, int value)
{
int ch=0,reg=0;
if (data < 0x80)
@@ -266,8 +180,8 @@ void qsound_set_command(int data, int value)
{
case 0: /* Bank */
ch=(ch+1)&0x0f; /* strange ... */
- qsound_channel[ch].bank=(value&0x7f)<<16;
- qsound_channel[ch].bank /= LENGTH_DIV;
+ qs->qsound_channel[ch].bank=(value&0x7f)<<16;
+ qs->qsound_channel[ch].bank /= LENGTH_DIV;
#ifdef MAME_DEBUG
if (!value & 0x8000)
{
@@ -280,16 +194,16 @@ void qsound_set_command(int data, int value)
break;
case 1: /* start */
// printf("QS: key on ch %02d\n", ch);
- qsound_channel[ch].address=value;
- qsound_channel[ch].address/=LENGTH_DIV;
+ qs->qsound_channel[ch].address=value;
+ qs->qsound_channel[ch].address/=LENGTH_DIV;
break;
case 2: /* pitch */
#if QSOUND_DRIVER1
- qsound_channel[ch].pitch=(long)
- ((float)value * qsound_frq_ratio );
- qsound_channel[ch].pitch/=LENGTH_DIV;
+ qs->qsound_channel[ch].pitch=(long)
+ ((float)value * qs->qsound_frq_ratio );
+ qs->qsound_channel[ch].pitch/=LENGTH_DIV;
#else
- qsound_channel[ch].factor=((float) (value*(6/LENGTH_DIV)) /
+ qs->qsound_channel[ch].factor=((float) (value*(6/LENGTH_DIV)) /
(float) Machine->sample_rate)*256.0;
#endif
@@ -297,11 +211,11 @@ void qsound_set_command(int data, int value)
{
/* Key off */
// printf("QS: key off ch %02d\n", ch);
- qsound_channel[ch].key=0;
+ qs->qsound_channel[ch].key=0;
}
break;
case 3: /* unknown */
- qsound_channel[ch].reg3=value;
+ qs->qsound_channel[ch].reg3=value;
#ifdef MAME_DEBUG
if (value != 0x8000)
{
@@ -312,31 +226,31 @@ void qsound_set_command(int data, int value)
#endif
break;
case 4: /* loop offset */
- qsound_channel[ch].loop=value/LENGTH_DIV;
+ qs->qsound_channel[ch].loop=value/LENGTH_DIV;
break;
case 5: /* end */
- qsound_channel[ch].end=value/LENGTH_DIV;
+ qs->qsound_channel[ch].end=value/LENGTH_DIV;
break;
case 6: /* master volume */
if (value==0)
{
/* Key off */
- qsound_channel[ch].key=0;
+ qs->qsound_channel[ch].key=0;
}
- else if (qsound_channel[ch].key==0)
+ else if (qs->qsound_channel[ch].key==0)
{
/* Key on */
- qsound_channel[ch].key=1;
+ qs->qsound_channel[ch].key=1;
#if QSOUND_DRIVER1
- qsound_channel[ch].offset=0;
- qsound_channel[ch].lastdt=0;
+ qs->qsound_channel[ch].offset=0;
+ qs->qsound_channel[ch].lastdt=0;
#else
- qsound_channel[ch].cursor=qsound_channel[ch].address <<8 ;
- qsound_channel[ch].buffer=qsound_sample_rom+
- qsound_channel[ch].bank;
+ qs->qsound_channel[ch].cursor=qs->qsound_channel[ch].address <<8 ;
+ qs->qsound_channel[ch].buffer=qsound_sample_rom+
+ qs->qsound_channel[ch].bank;
#endif
}
- qsound_channel[ch].vol=value;
+ qs->qsound_channel[ch].vol=value;
#if QSOUND_DRIVER2
calcula_mix(ch);
#endif
@@ -360,17 +274,17 @@ void qsound_set_command(int data, int value)
{
pandata=32;
}
- qsound_channel[ch].rvol=qsound_pan_table[pandata];
- qsound_channel[ch].lvol=qsound_pan_table[32-pandata];
+ qs->qsound_channel[ch].rvol=qs->qsound_pan_table[pandata];
+ qs->qsound_channel[ch].lvol=qs->qsound_pan_table[32-pandata];
#endif
- qsound_channel[ch].pan = value;
+ qs->qsound_channel[ch].pan = value;
#if QSOUND_DRIVER2
calcula_mix(ch);
#endif
}
break;
case 9:
- qsound_channel[ch].reg9=value;
+ qs->qsound_channel[ch].reg9=value;
/*
#ifdef MAME_DEBUG
{
@@ -391,11 +305,11 @@ void qsound_set_command(int data, int value)
/* Driver 1 - based on the Amuse source */
-void qsound_update( int num, INT16 **buffer, int length )
+void qsound_update(qsound_state_t *qs, int num, INT16 **buffer, int length )
{
int i,j;
int rvol, lvol, count;
- struct QSOUND_CHANNEL *pC=&qsound_channel[0];
+ struct QSOUND_CHANNEL *pC=&qs->qsound_channel[0];
QSOUND_SRC_SAMPLE * pST;
QSOUND_SAMPLE *datap[2];
@@ -411,7 +325,7 @@ void qsound_update( int num, INT16 **buffer, int length )
{
QSOUND_SAMPLE *pOutL=datap[0];
QSOUND_SAMPLE *pOutR=datap[1];
- pST=qsound_sample_rom+pC->bank;
+ pST=qs->qsound_sample_rom+pC->bank;
rvol=(pC->rvol*pC->vol)>>(8*LENGTH_DIV);
lvol=(pC->lvol*pC->vol)>>(8*LENGTH_DIV);
@@ -465,7 +379,7 @@ void qsound_update( int num, INT16 **buffer, int length )
void calcula_mix(int channel)
{
int factl,factr;
- struct QSOUND_CHANNEL *pC=&qsound_channel[channel];
+ struct qs->qsound_channel *pC=&qs->qsound_channel[channel];
int vol=pC->vol>>5;
int pan=((pC->pan&0xFF)-0x10)<<3;
pC->mixl=vol;
@@ -484,12 +398,12 @@ void qsound_update(int num,void **buffer,int length)
{
int i,j;
QSOUND_SAMPLE *bufL,*bufR, sample;
- struct QSOUND_CHANNEL *pC=qsound_channel;
+ struct qs->qsound_channel *pC=qs->qsound_channel;
memset( buffer[0], 0x00, length * sizeof(QSOUND_SAMPLE) );
memset( buffer[1], 0x00, length * sizeof(QSOUND_SAMPLE) );
- for(j=0;j<QSOUND_CHANNELS;++j)
+ for(j=0;j<qs->qsound_channelS;++j)
{
bufL=(QSOUND_SAMPLE *) buffer[0];
bufR=(QSOUND_SAMPLE *) buffer[1];
diff --git a/plugins/ao/eng_qsf/qsound.h b/plugins/ao/eng_qsf/qsound.h
index 0a9462cf..3d4538a6 100644
--- a/plugins/ao/eng_qsf/qsound.h
+++ b/plugins/ao/eng_qsf/qsound.h
@@ -15,13 +15,103 @@ struct QSound_interface
char *sample_rom; /* sample data */
};
-int qsound_sh_start( struct QSound_interface *qsintf );
-void qsound_sh_stop( void );
-
-void qsound_data_h_w(int data);
-void qsound_data_l_w(int data);
-void qsound_cmd_w(int data);
-int qsound_status_r(void);
-void qsound_update( int num, INT16 **buffer, int length );
+
+/*
+Two Q sound drivers:
+DRIVER1 Based on the Amuse source
+DRIVER2 Miguel Angel Horna (mahorna@teleline.es)
+*/
+#define QSOUND_DRIVER1 1
+/*
+I don't know whether this system uses 8 bit or 16 bit samples.
+If it uses 16 bit samples then the sample ROM loading macros need
+to be modified to work with non-intel machines.
+*/
+#define QSOUND_8BIT_SAMPLES 1
+
+/*
+Debug defines
+*/
+#define LOG_WAVE 0
+#define LOG_QSOUND 0
+
+/* Typedefs & defines */
+
+#define QSOUND_DRIVER2 !QSOUND_DRIVER1
+
+#if QSOUND_8BIT_SAMPLES
+/* 8 bit source ROM samples */
+typedef signed char QSOUND_SRC_SAMPLE;
+#define LENGTH_DIV 1
+#else
+/* 8 bit source ROM samples */
+typedef signed short QSOUND_SRC_SAMPLE;
+#define LENGTH_DIV 2
+#endif
+
+#define QSOUND_CLOCKDIV 166 /* Clock divider */
+#define QSOUND_CHANNELS 16
+typedef INT16 QSOUND_SAMPLE;
+
+struct QSOUND_CHANNEL
+{
+ int bank; /* bank (x16) */
+ int address; /* start address */
+ int pitch; /* pitch */
+ int reg3; /* unknown (always 0x8000) */
+ int loop; /* loop address */
+ int end; /* end address */
+ int vol; /* master volume */
+ int pan; /* Pan value */
+ int reg9; /* unknown */
+
+ /* Work variables */
+ int key; /* Key on / key off */
+
+#if QSOUND_DRIVER1
+ int lvol; /* left volume */
+ int rvol; /* right volume */
+ int lastdt; /* last sample value */
+ int offset; /* current offset counter */
+#else
+ QSOUND_SRC_SAMPLE *buffer;
+ int factor; /*step factor (fixed point 8-bit)*/
+ int mixl,mixr; /*mixing factor (fixed point)*/
+ int cursor; /*current sample position (fixed point)*/
+ int lpos; /*last cursor pos*/
+ int lastsaml; /*last left sample (to avoid any calculation)*/
+ int lastsamr; /*last right sample*/
+#endif
+};
+
+
+typedef struct {
+ /* Private variables */
+ struct QSound_interface intf; /* Interface */
+ int qsound_stream; /* Audio stream */
+ struct QSOUND_CHANNEL qsound_channel[QSOUND_CHANNELS];
+ int qsound_data; /* register latch data */
+ QSOUND_SRC_SAMPLE *qsound_sample_rom; /* Q sound sample ROM */
+
+#if QSOUND_DRIVER1
+ int qsound_pan_table[33]; /* Pan volume table */
+ float qsound_frq_ratio; /* Frequency ratio */
+#endif
+
+#if LOG_WAVE
+ FILE *fpRawDataL;
+ FILE *fpRawDataR;
+#endif
+} qsound_state_t;
+
+qsound_state_t *qsound_sh_start(struct QSound_interface *qsintf);
+void qsound_sh_stop(qsound_state_t *qs);
+
+void qsound_data_h_w(qsound_state_t *qs, int data);
+void qsound_data_l_w(qsound_state_t *qs, int data);
+void qsound_cmd_w(qsound_state_t *qs, int data);
+int qsound_status_r(qsound_state_t *qs);
+void qsound_update(qsound_state_t *qs, int num, INT16 **buffer, int length);
+void qsound_set_command(qsound_state_t *qs, int data, int value);
#endif /* __QSOUND_H__ */