~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/emu/sound/2610intf.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 
3
 
  2610intf.c
4
 
 
5
 
  The YM2610 emulator supports up to 2 chips.
6
 
  Each chip has the following connections:
7
 
  - Status Read / Control Write A
8
 
  - Port Read / Data Write A
9
 
  - Control Write B
10
 
  - Data Write B
11
 
 
12
 
***************************************************************************/
13
 
 
14
 
#include "emu.h"
15
 
#include "ay8910.h"
16
 
#include "2610intf.h"
17
 
#include "fm.h"
18
 
 
19
 
typedef struct _ym2610_state ym2610_state;
20
 
struct _ym2610_state
21
 
{
22
 
        sound_stream *  stream;
23
 
        emu_timer *             timer[2];
24
 
        void *                  chip;
25
 
        void *                  psg;
26
 
        const ym2610_interface *intf;
27
 
        device_t *device;
28
 
};
29
 
 
30
 
 
31
 
INLINE ym2610_state *get_safe_token(device_t *device)
32
 
{
33
 
        assert(device != NULL);
34
 
        assert(device->type() == YM2610 || device->type() == YM2610B);
35
 
        return (ym2610_state *)downcast<legacy_device_base *>(device)->token();
36
 
}
37
 
 
38
 
 
39
 
static void psg_set_clock(void *param, int clock)
40
 
{
41
 
        ym2610_state *info = (ym2610_state *)param;
42
 
        ay8910_set_clock_ym(info->psg, clock);
43
 
}
44
 
 
45
 
static void psg_write(void *param, int address, int data)
46
 
{
47
 
        ym2610_state *info = (ym2610_state *)param;
48
 
        ay8910_write_ym(info->psg, address, data);
49
 
}
50
 
 
51
 
static int psg_read(void *param)
52
 
{
53
 
        ym2610_state *info = (ym2610_state *)param;
54
 
        return ay8910_read_ym(info->psg);
55
 
}
56
 
 
57
 
static void psg_reset(void *param)
58
 
{
59
 
        ym2610_state *info = (ym2610_state *)param;
60
 
        ay8910_reset_ym(info->psg);
61
 
}
62
 
 
63
 
static const ssg_callbacks psgintf =
64
 
{
65
 
        psg_set_clock,
66
 
        psg_write,
67
 
        psg_read,
68
 
        psg_reset
69
 
};
70
 
 
71
 
/*------------------------- TM2610 -------------------------------*/
72
 
/* IRQ Handler */
73
 
static void IRQHandler(void *param,int irq)
74
 
{
75
 
        ym2610_state *info = (ym2610_state *)param;
76
 
        if(info->intf->handler) info->intf->handler(info->device, irq);
77
 
}
78
 
 
79
 
/* Timer overflow callback from timer.c */
80
 
static TIMER_CALLBACK( timer_callback_0 )
81
 
{
82
 
        ym2610_state *info = (ym2610_state *)ptr;
83
 
        ym2610_timer_over(info->chip,0);
84
 
}
85
 
 
86
 
static TIMER_CALLBACK( timer_callback_1 )
87
 
{
88
 
        ym2610_state *info = (ym2610_state *)ptr;
89
 
        ym2610_timer_over(info->chip,1);
90
 
}
91
 
 
92
 
static void timer_handler(void *param,int c,int count,int clock)
93
 
{
94
 
        ym2610_state *info = (ym2610_state *)param;
95
 
        if( count == 0 )
96
 
        {       /* Reset FM Timer */
97
 
                info->timer[c]->enable(false);
98
 
        }
99
 
        else
100
 
        {       /* Start FM Timer */
101
 
                attotime period = attotime::from_hz(clock) * count;
102
 
 
103
 
                if (!info->timer[c]->enable(true))
104
 
                        info->timer[c]->adjust(period);
105
 
        }
106
 
}
107
 
 
108
 
/* update request from fm.c */
109
 
void ym2610_update_request(void *param)
110
 
{
111
 
        ym2610_state *info = (ym2610_state *)param;
112
 
        info->stream->update();
113
 
}
114
 
 
115
 
 
116
 
static STREAM_UPDATE( ym2610_stream_update )
117
 
{
118
 
        ym2610_state *info = (ym2610_state *)param;
119
 
        ym2610_update_one(info->chip, outputs, samples);
120
 
}
121
 
 
122
 
static STREAM_UPDATE( ym2610b_stream_update )
123
 
{
124
 
        ym2610_state *info = (ym2610_state *)param;
125
 
        ym2610b_update_one(info->chip, outputs, samples);
126
 
}
127
 
 
128
 
 
129
 
static void ym2610_intf_postload(ym2610_state *info)
130
 
{
131
 
        ym2610_postload(info->chip);
132
 
}
133
 
 
134
 
 
135
 
static DEVICE_START( ym2610 )
136
 
{
137
 
        static const ym2610_interface generic_2610 = { 0 };
138
 
        static const ay8910_interface generic_ay8910 =
139
 
        {
140
 
                AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT,
141
 
                AY8910_DEFAULT_LOADS,
142
 
                DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL
143
 
        };
144
 
        const ym2610_interface *intf = device->static_config() ? (const ym2610_interface *)device->static_config() : &generic_2610;
145
 
        int rate = device->clock()/72;
146
 
        void *pcmbufa,*pcmbufb;
147
 
        int  pcmsizea,pcmsizeb;
148
 
        ym2610_state *info = get_safe_token(device);
149
 
        astring name;
150
 
        device_type type = device->type();
151
 
 
152
 
        info->intf = intf;
153
 
        info->device = device;
154
 
        info->psg = ay8910_start_ym(NULL, device->type(), device, device->clock(), &generic_ay8910);
155
 
        assert_always(info->psg != NULL, "Error creating YM2610/AY8910 chip");
156
 
 
157
 
        /* Timer Handler set */
158
 
        info->timer[0] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_0), info);
159
 
        info->timer[1] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_1), info);
160
 
 
161
 
        /* stream system initialize */
162
 
        info->stream = device->machine().sound().stream_alloc(*device,0,2,rate,info,(type == YM2610) ? ym2610_stream_update : ym2610b_stream_update);
163
 
        /* setup adpcm buffers */
164
 
        pcmbufa  = *device->region();
165
 
        pcmsizea = device->region()->bytes();
166
 
        name.printf("%s.deltat", device->tag());
167
 
        pcmbufb  = (void *)(device->machine().region(name)->base());
168
 
        pcmsizeb = device->machine().region(name)->bytes();
169
 
        if (pcmbufb == NULL || pcmsizeb == 0)
170
 
        {
171
 
                pcmbufb = pcmbufa;
172
 
                pcmsizeb = pcmsizea;
173
 
        }
174
 
 
175
 
        /**** initialize YM2610 ****/
176
 
        info->chip = ym2610_init(info,device,device->clock(),rate,
177
 
                           pcmbufa,pcmsizea,pcmbufb,pcmsizeb,
178
 
                           timer_handler,IRQHandler,&psgintf);
179
 
        assert_always(info->chip != NULL, "Error creating YM2610 chip");
180
 
 
181
 
        device->machine().save().register_postload(save_prepost_delegate(FUNC(ym2610_intf_postload), info));
182
 
}
183
 
 
184
 
static DEVICE_STOP( ym2610 )
185
 
{
186
 
        ym2610_state *info = get_safe_token(device);
187
 
        ym2610_shutdown(info->chip);
188
 
        ay8910_stop_ym(info->psg);
189
 
}
190
 
 
191
 
static DEVICE_RESET( ym2610 )
192
 
{
193
 
        ym2610_state *info = get_safe_token(device);
194
 
        ym2610_reset_chip(info->chip);
195
 
}
196
 
 
197
 
 
198
 
READ8_DEVICE_HANDLER( ym2610_r )
199
 
{
200
 
        ym2610_state *info = get_safe_token(device);
201
 
        return ym2610_read(info->chip, offset & 3);
202
 
}
203
 
 
204
 
WRITE8_DEVICE_HANDLER( ym2610_w )
205
 
{
206
 
        ym2610_state *info = get_safe_token(device);
207
 
        ym2610_write(info->chip, offset & 3, data);
208
 
}
209
 
 
210
 
 
211
 
READ8_DEVICE_HANDLER( ym2610_status_port_a_r ) { return ym2610_r(device, 0); }
212
 
READ8_DEVICE_HANDLER( ym2610_status_port_b_r ) { return ym2610_r(device, 2); }
213
 
READ8_DEVICE_HANDLER( ym2610_read_port_r ) { return ym2610_r(device, 1); }
214
 
 
215
 
WRITE8_DEVICE_HANDLER( ym2610_control_port_a_w ) { ym2610_w(device, 0, data); }
216
 
WRITE8_DEVICE_HANDLER( ym2610_control_port_b_w ) { ym2610_w(device, 2, data); }
217
 
WRITE8_DEVICE_HANDLER( ym2610_data_port_a_w ) { ym2610_w(device, 1, data); }
218
 
WRITE8_DEVICE_HANDLER( ym2610_data_port_b_w ) { ym2610_w(device, 3, data); }
219
 
 
220
 
 
221
 
 
222
 
/**************************************************************************
223
 
 * Generic get_info
224
 
 **************************************************************************/
225
 
 
226
 
DEVICE_GET_INFO( ym2610 )
227
 
{
228
 
        switch (state)
229
 
        {
230
 
                /* --- the following bits of info are returned as 64-bit signed integers --- */
231
 
                case DEVINFO_INT_TOKEN_BYTES:                                   info->i = sizeof(ym2610_state);                         break;
232
 
 
233
 
                /* --- the following bits of info are returned as pointers to data or functions --- */
234
 
                case DEVINFO_FCT_START:                                                 info->start = DEVICE_START_NAME( ym2610 );                              break;
235
 
                case DEVINFO_FCT_STOP:                                                  info->stop = DEVICE_STOP_NAME( ym2610 );                                break;
236
 
                case DEVINFO_FCT_RESET:                                                 info->reset = DEVICE_RESET_NAME( ym2610 );                              break;
237
 
 
238
 
                /* --- the following bits of info are returned as NULL-terminated strings --- */
239
 
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "YM2610");                                                      break;
240
 
                case DEVINFO_STR_FAMILY:                                        strcpy(info->s, "Yamaha FM");                                           break;
241
 
                case DEVINFO_STR_VERSION:                                       strcpy(info->s, "1.0");                                                         break;
242
 
                case DEVINFO_STR_SOURCE_FILE:                                           strcpy(info->s, __FILE__);                                                      break;
243
 
                case DEVINFO_STR_CREDITS:                                       strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
244
 
        }
245
 
}
246
 
 
247
 
DEVICE_GET_INFO( ym2610b )
248
 
{
249
 
        switch (state)
250
 
        {
251
 
                /* --- the following bits of info are returned as NULL-terminated strings --- */
252
 
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "YM2610B");                                     break;
253
 
 
254
 
                default:                                                                                DEVICE_GET_INFO_CALL(ym2610);                           break;
255
 
        }
256
 
}
257
 
 
258
 
 
259
 
DEFINE_LEGACY_SOUND_DEVICE(YM2610, ym2610);
260
 
DEFINE_LEGACY_SOUND_DEVICE(YM2610B, ym2610b);