OpenCores
URL https://opencores.org/ocsvn/sqmusic/sqmusic/trunk

Subversion Repositories sqmusic

[/] [sqmusic/] [trunk/] [mame/] [2203intf.c] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 gryzor
#include "emu.h"
2
#include "2203intf.h"
3
#include "fm.h"
4
 
5
 
6
struct ym2203_state
7
{
8
        sound_stream *  stream;
9
        emu_timer *     timer[2];
10
        void *          chip;
11
        void *          psg;
12
        const ym2203_interface *intf;
13
        devcb_resolved_write_line irqhandler;
14
        device_t *device;
15
};
16
 
17
 
18
INLINE ym2203_state *get_safe_token(device_t *device)
19
{
20
        assert(device != NULL);
21
        assert(device->type() == YM2203);
22
        return (ym2203_state *)downcast<ym2203_device *>(device)->token();
23
}
24
 
25
 
26
static void psg_set_clock(void *param, int clock)
27
{
28
        ym2203_state *info = (ym2203_state *)param;
29
        ay8910_set_clock_ym(info->psg, clock);
30
}
31
 
32
static void psg_write(void *param, int address, int data)
33
{
34
        ym2203_state *info = (ym2203_state *)param;
35
        ay8910_write_ym(info->psg, address, data);
36
}
37
 
38
static int psg_read(void *param)
39
{
40
        ym2203_state *info = (ym2203_state *)param;
41
        return ay8910_read_ym(info->psg);
42
}
43
 
44
static void psg_reset(void *param)
45
{
46
        ym2203_state *info = (ym2203_state *)param;
47
        ay8910_reset_ym(info->psg);
48
}
49
 
50
static const ssg_callbacks psgintf =
51
{
52
        psg_set_clock,
53
        psg_write,
54
        psg_read,
55
        psg_reset
56
};
57
 
58
/* IRQ Handler */
59
static void IRQHandler(void *param,int irq)
60
{
61
        ym2203_state *info = (ym2203_state *)param;
62
        if (!info->irqhandler.isnull())
63
                info->irqhandler(irq);
64
}
65
 
66
/* Timer overflow callback from timer.c */
67
static TIMER_CALLBACK( timer_callback_2203_0 )
68
{
69
        ym2203_state *info = (ym2203_state *)ptr;
70
        ym2203_timer_over(info->chip,0);
71
}
72
 
73
static TIMER_CALLBACK( timer_callback_2203_1 )
74
{
75
        ym2203_state *info = (ym2203_state *)ptr;
76
        ym2203_timer_over(info->chip,1);
77
}
78
 
79
/* update request from fm.c */
80
void ym2203_update_request(void *param)
81
{
82
        ym2203_state *info = (ym2203_state *)param;
83
        info->stream->update();
84
}
85
 
86
 
87
static void timer_handler(void *param,int c,int count,int clock)
88
{
89
        ym2203_state *info = (ym2203_state *)param;
90
        if( count == 0 )
91
        {   /* Reset FM Timer */
92
                info->timer[c]->enable(false);
93
        }
94
        else
95
        {   /* Start FM Timer */
96
                attotime period = attotime::from_hz(clock) * count;
97
                if (!info->timer[c]->enable(true))
98
                        info->timer[c]->adjust(period);
99
        }
100
}
101
 
102
static STREAM_UPDATE( ym2203_stream_update )
103
{
104
        ym2203_state *info = (ym2203_state *)param;
105
        ym2203_update_one(info->chip, outputs[0], samples);
106
}
107
 
108
 
109
static void ym2203_intf_postload (ym2203_state *info)
110
{
111
        ym2203_postload(info->chip);
112
}
113
 
114
 
115
static DEVICE_START( ym2203 )
116
{
117
        static const ym2203_interface generic_2203 =
118
        {
119
                {
120
                        AY8910_LEGACY_OUTPUT,
121
                        AY8910_DEFAULT_LOADS,
122
                        DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL
123
                },
124
                DEVCB_NULL
125
        };
126
        const ym2203_interface *intf = device->static_config() ? (const ym2203_interface *)device->static_config() : &generic_2203;
127
        ym2203_state *info = get_safe_token(device);
128
        int rate = device->clock()/72; /* ??? */
129
 
130
        info->irqhandler.resolve(intf->irqhandler, *device);
131
        info->intf = intf;
132
        info->device = device;
133
        info->psg = ay8910_start_ym(NULL, YM2203, device, device->clock(), &intf->ay8910_intf);
134
        assert_always(info->psg != NULL, "Error creating YM2203/AY8910 chip");
135
 
136
        /* Timer Handler set */
137
        info->timer[0] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_2203_0), info);
138
        info->timer[1] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_2203_1), info);
139
 
140
        /* stream system initialize */
141
        info->stream = device->machine().sound().stream_alloc(*device,0,1,rate,info,ym2203_stream_update);
142
 
143
        /* Initialize FM emurator */
144
        info->chip = ym2203_init(info,device,device->clock(),rate,timer_handler,IRQHandler,&psgintf);
145
        assert_always(info->chip != NULL, "Error creating YM2203 chip");
146
 
147
        device->machine().save().register_postload(save_prepost_delegate(FUNC(ym2203_intf_postload), info));
148
}
149
 
150
static DEVICE_STOP( ym2203 )
151
{
152
        ym2203_state *info = get_safe_token(device);
153
        ym2203_shutdown(info->chip);
154
        ay8910_stop_ym(info->psg);
155
}
156
 
157
static DEVICE_RESET( ym2203 )
158
{
159
        ym2203_state *info = get_safe_token(device);
160
        ym2203_reset_chip(info->chip);
161
}
162
 
163
 
164
 
165
READ8_DEVICE_HANDLER( ym2203_r )
166
{
167
        ym2203_state *info = get_safe_token(device);
168
        return ym2203_read(info->chip, offset & 1);
169
}
170
 
171
WRITE8_DEVICE_HANDLER( ym2203_w )
172
{
173
        ym2203_state *info = get_safe_token(device);
174
        ym2203_write(info->chip, offset & 1, data);
175
}
176
 
177
 
178
READ8_DEVICE_HANDLER( ym2203_status_port_r ) { return ym2203_r(device, space, 0); }
179
READ8_DEVICE_HANDLER( ym2203_read_port_r ) { return ym2203_r(device, space, 1); }
180
WRITE8_DEVICE_HANDLER( ym2203_control_port_w ) { ym2203_w(device, space, 0, data); }
181
WRITE8_DEVICE_HANDLER( ym2203_write_port_w ) { ym2203_w(device, space, 1, data); }
182
 
183
const device_type YM2203 = &device_creator<ym2203_device>;
184
 
185
ym2203_device::ym2203_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
186
        : device_t(mconfig, YM2203, "YM2203", tag, owner, clock),
187
                device_sound_interface(mconfig, *this)
188
{
189
        m_token = global_alloc_clear(ym2203_state);
190
}
191
 
192
//-------------------------------------------------
193
//  device_config_complete - perform any
194
//  operations now that the configuration is
195
//  complete
196
//-------------------------------------------------
197
 
198
void ym2203_device::device_config_complete()
199
{
200
}
201
 
202
//-------------------------------------------------
203
//  device_start - device-specific startup
204
//-------------------------------------------------
205
 
206
void ym2203_device::device_start()
207
{
208
        DEVICE_START_NAME( ym2203 )(this);
209
}
210
 
211
//-------------------------------------------------
212
//  device_reset - device-specific reset
213
//-------------------------------------------------
214
 
215
void ym2203_device::device_reset()
216
{
217
        DEVICE_RESET_NAME( ym2203 )(this);
218
}
219
 
220
//-------------------------------------------------
221
//  device_stop - device-specific stop
222
//-------------------------------------------------
223
 
224
void ym2203_device::device_stop()
225
{
226
        DEVICE_STOP_NAME( ym2203 )(this);
227
}
228
 
229
//-------------------------------------------------
230
//  sound_stream_update - handle a stream update
231
//-------------------------------------------------
232
 
233
void ym2203_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
234
{
235
        // should never get here
236
        fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
237
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.