~ubuntu-branches/ubuntu/karmic/xmame/karmic

« back to all changes in this revision

Viewing changes to src/sound/2608intf.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno Barrera C.
  • Date: 2007-02-16 10:06:54 UTC
  • mfrom: (2.1.5 edgy)
  • Revision ID: james.westby@ubuntu.com-20070216100654-iztas2cl47k5j039
Tags: 0.106-2
* Added Italian debconf templates translation. (closes: #382672)
* Added German debconf templates translation. (closes: #396610)
* Added Japanese debconf templates translation. (closes: #400011)
* Added Portuguese debconf templates translation. (closes: #409960)

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
***************************************************************************/
13
13
 
14
 
#include "driver.h"
 
14
#include "sndintrf.h"
 
15
#include "streams.h"
15
16
#include "ay8910.h"
16
17
#include "2608intf.h"
17
18
#include "fm.h"
18
19
 
19
20
#ifdef BUILD_YM2608
20
21
 
21
 
#define YM2608_NUMBUF 2
22
 
/* use FM.C with stream system */
23
 
 
24
 
static int stream[MAX_2608];
25
 
 
26
 
/* Global Interface holder */
27
 
static const struct YM2608interface *intf;
28
 
 
29
 
static void *Timer[MAX_2608][2];
 
22
struct ym2608_info
 
23
{
 
24
        sound_stream *  stream;
 
25
        mame_timer *    timer[2];
 
26
        void *                  chip;
 
27
        void *                  psg;
 
28
        const struct YM2608interface *intf;
 
29
};
 
30
 
 
31
 
 
32
 
 
33
static void psg_set_clock(void *param, int clock)
 
34
{
 
35
        struct ym2608_info *info = param;
 
36
        ay8910_set_clock_ym(info->psg, clock);
 
37
}
 
38
 
 
39
static void psg_write(void *param, int address, int data)
 
40
{
 
41
        struct ym2608_info *info = param;
 
42
        ay8910_write_ym(info->psg, address, data);
 
43
}
 
44
 
 
45
static int psg_read(void *param)
 
46
{
 
47
        struct ym2608_info *info = param;
 
48
        return ay8910_read_ym(info->psg);
 
49
}
 
50
 
 
51
static void psg_reset(void *param)
 
52
{
 
53
        struct ym2608_info *info = param;
 
54
        ay8910_reset_ym(info->psg);
 
55
}
 
56
 
 
57
static const struct ssg_callbacks psgintf =
 
58
{
 
59
        psg_set_clock,
 
60
        psg_write,
 
61
        psg_read,
 
62
        psg_reset
 
63
};
30
64
 
31
65
 
32
66
/* IRQ Handler */
33
 
static void IRQHandler(int n,int irq)
 
67
static void IRQHandler(void *param,int irq)
34
68
{
35
 
        if(intf->handler[n]) intf->handler[n](irq);
 
69
        struct ym2608_info *info = param;
 
70
        if(info->intf->handler) info->intf->handler(irq);
36
71
}
37
72
 
38
73
/* Timer overflow callback from timer.c */
39
 
static void timer_callback_2608(int param)
 
74
static void timer_callback_2608_0(void *param)
40
75
{
41
 
        int n=param&0x7f;
42
 
        int c=param>>7;
 
76
        struct ym2608_info *info = param;
 
77
        YM2608TimerOver(info->chip,0);
 
78
}
43
79
 
44
 
        YM2608TimerOver(n,c);
 
80
static void timer_callback_2608_1(void *param)
 
81
{
 
82
        struct ym2608_info *info = param;
 
83
        YM2608TimerOver(info->chip,1);
45
84
}
46
85
 
47
86
/* TimerHandler from fm.c */
48
 
static void TimerHandler(int n,int c,int count,double stepTime)
 
87
static void TimerHandler(void *param,int c,int count,double stepTime)
49
88
{
 
89
        struct ym2608_info *info = param;
50
90
        if( count == 0 )
51
91
        {       /* Reset FM Timer */
52
 
                timer_enable(Timer[n][c], 0);
 
92
                timer_enable(info->timer[c], 0);
53
93
        }
54
94
        else
55
95
        {       /* Start FM Timer */
56
96
                double timeSec = (double)count * stepTime;
57
 
                if (!timer_enable(Timer[n][c], 1))
58
 
                        timer_adjust(Timer[n][c], timeSec, (c<<7)|n, 0);
59
 
        }
60
 
}
61
 
 
62
 
static void FMTimerInit( void )
63
 
{
64
 
        int i;
65
 
 
66
 
        for( i = 0 ; i < MAX_2608 ; i++ )
67
 
        {
68
 
                Timer[i][0] = timer_alloc(timer_callback_2608);
69
 
                Timer[i][1] = timer_alloc(timer_callback_2608);
 
97
                if (!timer_enable(info->timer[c], 1))
 
98
                        timer_adjust_ptr(info->timer[c], timeSec, 0);
70
99
        }
71
100
}
72
101
 
73
102
/* update request from fm.c */
74
 
void YM2608UpdateRequest(int chip)
75
 
{
76
 
        stream_update(stream[chip],100);
77
 
}
78
 
 
79
 
int YM2608_sh_start(const struct MachineSound *msound)
80
 
{
81
 
        int i,j;
 
103
void YM2608UpdateRequest(void *param)
 
104
{
 
105
        struct ym2608_info *info = param;
 
106
        stream_update(info->stream,100);
 
107
}
 
108
 
 
109
static void ym2608_stream_update(void *param, stream_sample_t **inputs, stream_sample_t **buffers, int length)
 
110
{
 
111
        struct ym2608_info *info = param;
 
112
        YM2608UpdateOne(info->chip, buffers, length);
 
113
}
 
114
 
 
115
 
 
116
static void ym2608_postload(void *param)
 
117
{
 
118
        struct ym2608_info *info = param;
 
119
        YM2608Postload(info->chip);
 
120
}
 
121
 
 
122
 
 
123
static void *ym2608_start(int sndindex, int clock, const void *config)
 
124
{
 
125
        static const struct YM2608interface generic_2608 = { 0 };
 
126
        const struct YM2608interface *intf = config ? config : &generic_2608;
82
127
        int rate = Machine->sample_rate;
83
 
        char buf[YM2608_NUMBUF][40];
84
 
        const char *name[YM2608_NUMBUF];
85
 
        int mixed_vol,vol[YM2608_NUMBUF];
86
 
        void *pcmbufa[YM2608_NUMBUF];
87
 
        int  pcmsizea[YM2608_NUMBUF];
88
 
 
89
 
 
90
 
        intf = msound->sound_interface;
91
 
        if( intf->num > MAX_2608 ) return 1;
92
 
 
93
 
        if (AY8910_sh_start_ym(msound)) return 1;
 
128
        void *pcmbufa;
 
129
        int  pcmsizea;
 
130
 
 
131
        struct ym2608_info *info;
 
132
 
 
133
        info = auto_malloc(sizeof(*info));
 
134
        memset(info, 0, sizeof(*info));
 
135
 
 
136
        info->intf = intf;
 
137
        info->psg = ay8910_start_ym(SOUND_YM2608, sndindex, clock, 1, intf->portAread, intf->portBread, intf->portAwrite, intf->portBwrite);
 
138
        if (!info->psg) return NULL;
94
139
 
95
140
        /* Timer Handler set */
96
 
        FMTimerInit();
 
141
        info->timer[0] =timer_alloc_ptr(timer_callback_2608_0, info);
 
142
        info->timer[1] =timer_alloc_ptr(timer_callback_2608_1, info);
97
143
 
98
144
        /* stream system initialize */
99
 
        for (i = 0;i < intf->num;i++)
100
 
        {
101
 
                /* stream setup */
102
 
                mixed_vol = intf->volumeFM[i];
103
 
                /* stream setup */
104
 
                for (j = 0 ; j < YM2608_NUMBUF ; j++)
105
 
                {
106
 
                        name[j]=buf[j];
107
 
                        vol[j] = mixed_vol & 0xffff;
108
 
                        mixed_vol>>=16;
109
 
                        sprintf(buf[j],"%s #%d Ch%d",sound_name(msound),i,j+1);
110
 
                }
111
 
                stream[i] = stream_init_multi(YM2608_NUMBUF,name,vol,rate,i,YM2608UpdateOne);
112
 
                /* setup adpcm buffers */
113
 
                pcmbufa[i]  = (void *)(memory_region(intf->pcmrom[i]));
114
 
                pcmsizea[i] = memory_region_length(intf->pcmrom[i]);
115
 
        }
116
 
 
 
145
        info->stream = stream_create(0,2,rate,info,ym2608_stream_update);
 
146
        /* setup adpcm buffers */
 
147
        pcmbufa  = (void *)(memory_region(info->intf->pcmrom));
 
148
        pcmsizea = memory_region_length(info->intf->pcmrom);
117
149
 
118
150
        /* initialize YM2608 */
119
 
        if (YM2608Init(intf->num,intf->baseclock,rate,
 
151
        info->chip = YM2608Init(info,sndindex,clock,rate,
120
152
                           pcmbufa,pcmsizea,
121
 
                           TimerHandler,IRQHandler) == 0)
122
 
                return 0;
 
153
                           TimerHandler,IRQHandler,&psgintf);
 
154
 
 
155
        state_save_register_func_postload_ptr(ym2608_postload, info);
 
156
 
 
157
        if (info->chip)
 
158
                return info;
123
159
 
124
160
        /* error */
125
 
        return 1;
126
 
}
127
 
 
128
 
/************************************************/
129
 
/* Sound Hardware Stop                                                  */
130
 
/************************************************/
131
 
void YM2608_sh_stop(void)
132
 
{
133
 
        YM2608Shutdown();
134
 
        AY8910_sh_stop_ym();
135
 
}
136
 
/* reset */
137
 
void YM2608_sh_reset(void)
138
 
{
139
 
        int i;
140
 
 
141
 
        for (i = 0;i < intf->num;i++)
142
 
                YM2608ResetChip(i);
143
 
}
144
 
 
145
 
/************************************************/
146
 
/* Status Read for YM2608 - Chip 0                              */
 
161
        return NULL;
 
162
}
 
163
 
 
164
static void ym2608_stop(void *token)
 
165
{
 
166
        struct ym2608_info *info = token;
 
167
        YM2608Shutdown(info->chip);
 
168
        ay8910_stop_ym(info->psg);
 
169
}
 
170
 
 
171
static void ym2608_reset(void *token)
 
172
{
 
173
        struct ym2608_info *info = token;
 
174
        YM2608ResetChip(info->chip);
 
175
}
 
176
 
 
177
/************************************************/
 
178
/* Status Read for YM2608 - Chip 0              */
147
179
/************************************************/
148
180
READ8_HANDLER( YM2608_status_port_0_A_r )
149
181
{
150
 
/*logerror("PC %04x: 2608 S0A=%02X\n",activecpu_get_pc(),YM2608Read(0,0)); */
151
 
        return YM2608Read(0,0);
 
182
/*logerror("PC %04x: 2608 S0A=%02X\n",activecpu_get_pc(),YM2608Read(sndti_token(SOUND_YM2608, 0),0)); */
 
183
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
 
184
        return YM2608Read(info->chip,0);
152
185
}
153
186
 
154
187
READ8_HANDLER( YM2608_status_port_0_B_r )
155
188
{
156
 
/*logerror("PC %04x: 2608 S0B=%02X\n",activecpu_get_pc(),YM2608Read(0,2)); */
157
 
        return YM2608Read(0,2);
 
189
/*logerror("PC %04x: 2608 S0B=%02X\n",activecpu_get_pc(),YM2608Read(sndti_token(SOUND_YM2608, 0),2)); */
 
190
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
 
191
        return YM2608Read(info->chip,2);
158
192
}
159
193
 
160
194
/************************************************/
161
 
/* Status Read for YM2608 - Chip 1                              */
 
195
/* Status Read for YM2608 - Chip 1              */
162
196
/************************************************/
163
197
READ8_HANDLER( YM2608_status_port_1_A_r ) {
164
 
        return YM2608Read(1,0);
 
198
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
 
199
        return YM2608Read(info->chip,0);
165
200
}
166
201
 
167
202
READ8_HANDLER( YM2608_status_port_1_B_r ) {
168
 
        return YM2608Read(1,2);
 
203
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
 
204
        return YM2608Read(info->chip,2);
169
205
}
170
206
 
171
207
/************************************************/
172
 
/* Port Read for YM2608 - Chip 0                                */
 
208
/* Port Read for YM2608 - Chip 0                */
173
209
/************************************************/
174
210
READ8_HANDLER( YM2608_read_port_0_r ){
175
 
        return YM2608Read(0,1);
 
211
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
 
212
        return YM2608Read(info->chip,1);
176
213
}
177
214
 
178
215
/************************************************/
179
 
/* Port Read for YM2608 - Chip 1                                */
 
216
/* Port Read for YM2608 - Chip 1                */
180
217
/************************************************/
181
218
READ8_HANDLER( YM2608_read_port_1_r ){
182
 
        return YM2608Read(1,1);
 
219
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
 
220
        return YM2608Read(info->chip,1);
183
221
}
184
222
 
185
223
/************************************************/
186
 
/* Control Write for YM2608 - Chip 0                    */
187
 
/* Consists of 2 addresses                                              */
 
224
/* Control Write for YM2608 - Chip 0            */
 
225
/* Consists of 2 addresses                      */
188
226
/************************************************/
189
227
WRITE8_HANDLER( YM2608_control_port_0_A_w )
190
228
{
191
 
        YM2608Write(0,0,data);
 
229
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
 
230
        YM2608Write(info->chip,0,data);
192
231
}
193
232
 
194
233
WRITE8_HANDLER( YM2608_control_port_0_B_w )
195
234
{
196
 
        YM2608Write(0,2,data);
 
235
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
 
236
        YM2608Write(info->chip,2,data);
197
237
}
198
238
 
199
239
/************************************************/
200
 
/* Control Write for YM2608 - Chip 1                    */
201
 
/* Consists of 2 addresses                                              */
 
240
/* Control Write for YM2608 - Chip 1            */
 
241
/* Consists of 2 addresses                      */
202
242
/************************************************/
203
243
WRITE8_HANDLER( YM2608_control_port_1_A_w ){
204
 
        YM2608Write(1,0,data);
 
244
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
 
245
        YM2608Write(info->chip,0,data);
205
246
}
206
247
 
207
248
WRITE8_HANDLER( YM2608_control_port_1_B_w ){
208
 
        YM2608Write(1,2,data);
 
249
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
 
250
        YM2608Write(info->chip,2,data);
209
251
}
210
252
 
211
253
/************************************************/
212
 
/* Data Write for YM2608 - Chip 0                               */
213
 
/* Consists of 2 addresses                                              */
 
254
/* Data Write for YM2608 - Chip 0               */
 
255
/* Consists of 2 addresses                      */
214
256
/************************************************/
215
257
WRITE8_HANDLER( YM2608_data_port_0_A_w )
216
258
{
217
 
        YM2608Write(0,1,data);
 
259
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
 
260
        YM2608Write(info->chip,1,data);
218
261
}
219
262
 
220
263
WRITE8_HANDLER( YM2608_data_port_0_B_w )
221
264
{
222
 
        YM2608Write(0,3,data);
 
265
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
 
266
        YM2608Write(info->chip,3,data);
223
267
}
224
268
 
225
269
/************************************************/
226
 
/* Data Write for YM2608 - Chip 1                               */
227
 
/* Consists of 2 addresses                                              */
 
270
/* Data Write for YM2608 - Chip 1               */
 
271
/* Consists of 2 addresses                      */
228
272
/************************************************/
229
273
WRITE8_HANDLER( YM2608_data_port_1_A_w ){
230
 
        YM2608Write(1,1,data);
 
274
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
 
275
        YM2608Write(info->chip,1,data);
231
276
}
232
277
WRITE8_HANDLER( YM2608_data_port_1_B_w ){
233
 
        YM2608Write(1,3,data);
 
278
        struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
 
279
        YM2608Write(info->chip,3,data);
234
280
}
235
281
 
236
282
/**************** end of file ****************/
237
283
 
 
284
 
 
285
/**************************************************************************
 
286
 * Generic get_info
 
287
 **************************************************************************/
 
288
 
 
289
static void ym2608_set_info(void *token, UINT32 state, sndinfo *info)
 
290
{
 
291
        switch (state)
 
292
        {
 
293
                /* no parameters to set */
 
294
        }
 
295
}
 
296
 
 
297
 
 
298
void ym2608_get_info(void *token, UINT32 state, sndinfo *info)
 
299
{
 
300
        switch (state)
 
301
        {
 
302
                /* --- the following bits of info are returned as 64-bit signed integers --- */
 
303
 
 
304
                /* --- the following bits of info are returned as pointers to data or functions --- */
 
305
                case SNDINFO_PTR_SET_INFO:                                              info->set_info = ym2608_set_info;               break;
 
306
                case SNDINFO_PTR_START:                                                 info->start = ym2608_start;                             break;
 
307
                case SNDINFO_PTR_STOP:                                                  info->stop = ym2608_stop;                               break;
 
308
                case SNDINFO_PTR_RESET:                                                 info->reset = ym2608_reset;                             break;
 
309
 
 
310
                /* --- the following bits of info are returned as NULL-terminated strings --- */
 
311
                case SNDINFO_STR_NAME:                                                  info->s = "YM2608";                                             break;
 
312
                case SNDINFO_STR_CORE_FAMILY:                                   info->s = "Yamaha FM";                                  break;
 
313
                case SNDINFO_STR_CORE_VERSION:                                  info->s = "1.0";                                                break;
 
314
                case SNDINFO_STR_CORE_FILE:                                             info->s = __FILE__;                                             break;
 
315
                case SNDINFO_STR_CORE_CREDITS:                                  info->s = "Copyright (c) 2004, The MAME Team"; break;
 
316
        }
 
317
}
 
318
 
238
319
#endif