summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/ymopn.cpp
blob: 2d1751ce8b03bde8d24171be314532864379feaf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
// license:BSD-3-Clause
// copyright-holders:Aaron Giles

#include "emu.h"
#include "ymopn.h"


//*********************************************************
//  YM2203 DEVICE
//*********************************************************

DEFINE_DEVICE_TYPE(YM2203, ym2203_device, "ym2203", "YM2203 OPN")

//-------------------------------------------------
//  ym2203_device - constructor
//-------------------------------------------------

ym2203_device::ym2203_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	ymfm_ssg_device_base<ymfm::ym2203>(mconfig, tag, owner, clock, YM2203)
{
}


//-------------------------------------------------
//  device_start - start of emulation
//-------------------------------------------------

void ym2203_device::device_start()
{
	// set our target output fidelity
	m_chip.set_fidelity(SSG_FIDELITY);

	// call our parent
	parent::device_start();
}



//*********************************************************
//  YM2608 DEVICE
//*********************************************************

DEFINE_DEVICE_TYPE(YM2608, ym2608_device, "ym2608", "YM2608 OPNA")

//-------------------------------------------------
//  ym2608_device - constructor
//-------------------------------------------------

ym2608_device::ym2608_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	ymfm_ssg_device_base<ymfm::ym2608>(mconfig, tag, owner, clock, YM2608),
	device_rom_interface(mconfig, *this),
	m_internal(*this, "internal")
{
}


//-------------------------------------------------
//  ym2608_device - start of emulation
//-------------------------------------------------

void ym2608_device::device_start()
{
	// set our target output fidelity
	m_chip.set_fidelity(SSG_FIDELITY);

	// call our parent
	parent::device_start();
}


//-------------------------------------------------
//  device_rom_region - return a pointer to our
//  ROM region
//-------------------------------------------------

ROM_START( ym2608 )
	ROM_REGION( 0x2000, "internal", 0 )
	//
	// While this rom was dumped by output analysis, not decap, it was tested
	// by playing it back into the chip as an external adpcm sample and produced
	// an identical dac result. a decap would be nice to verify things 100%,
	// but there is currently no reason to think this rom dump is incorrect.
	//
	// offset 0x0000: Source: 01BD.ROM  Length:  448 / 0x000001C0
	// offset 0x01C0: Source: 02SD.ROM  Length:  640 / 0x00000280
	// offset 0x0440: Source: 04TOP.ROM Length: 5952 / 0x00001740
	// offset 0x1B80: Source: 08HH.ROM  Length:  384 / 0x00000180
	// offset 0x1D00: Source: 10TOM.ROM Length:  640 / 0x00000280
	// offset 0x1F80: Source: 20RIM.ROM Length:  128 / 0x00000080
	//
	ROM_LOAD16_WORD( "ym2608_adpcm_rom.bin", 0x0000, 0x2000, CRC(23c9e0d8) SHA1(50b6c3e288eaa12ad275d4f323267bb72b0445df) )
ROM_END

const tiny_rom_entry *ym2608_device::device_rom_region() const
{
	return ROM_NAME( ym2608 );
}


//-------------------------------------------------
//  rom_bank_updated - refresh the stream if the
//  ROM banking changes
//-------------------------------------------------

void ym2608_device::rom_bank_updated()
{
	m_stream->update();
}


//-------------------------------------------------
//  ymfm_external_read - callback to read data for
//  the ADPCM-A/B engines
//-------------------------------------------------

uint8_t ym2608_device::ymfm_external_read(ymfm::access_class type, uint32_t offset)
{
	if (type == ymfm::ACCESS_ADPCM_A)
		return m_internal->as_u8(offset % m_internal->bytes());
	else if (type == ymfm::ACCESS_ADPCM_B)
		return space(0).read_byte(offset);
	return parent::ymfm_external_read(type, offset);
}


//-------------------------------------------------
//  ymfm_external_write - callback to write data to
//  the ADPCM-B engine; in this case, to our
//  default address space
//-------------------------------------------------

void ym2608_device::ymfm_external_write(ymfm::access_class type, uint32_t offset, uint8_t data)
{
	if (type == ymfm::ACCESS_ADPCM_B)
		return space(0).write_byte(offset, data);
	parent::ymfm_external_write(type, offset, data);
}



//*********************************************************
//  YM2610 DEVICE BASE
//*********************************************************

//-------------------------------------------------
//  ym2610_device_base - constructor
//-------------------------------------------------

template<typename ChipClass>
ym2610_device_base<ChipClass>::ym2610_device_base(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, device_type type) :
	ymfm_ssg_device_base<ChipClass>(mconfig, tag, owner, clock, type),
	device_memory_interface(mconfig, *this),
	m_adpcm_a_config("adpcm-a", ENDIANNESS_LITTLE, 8, 24, 0),
	m_adpcm_b_config("adpcm-b", ENDIANNESS_LITTLE, 8, 24, 0),
	m_adpcm_a_region(*this, "adpcma"),
	m_adpcm_b_region(*this, "adpcmb")
{
}


//-------------------------------------------------
//  memory_space_config - return a description of
//  any address spaces owned by this device
//-------------------------------------------------

template<typename ChipClass>
device_memory_interface::space_config_vector ym2610_device_base<ChipClass>::memory_space_config() const
{
	return space_config_vector{
		std::make_pair(0, &m_adpcm_a_config),
		std::make_pair(1, &m_adpcm_b_config)
	};
}


//-------------------------------------------------
//  device_start - start of emulation
//-------------------------------------------------

template<typename ChipClass>
void ym2610_device_base<ChipClass>::device_start()
{
	// set our target output fidelity
	parent::m_chip.set_fidelity(SSG_FIDELITY);

	// call our parent
	parent::device_start();

	// automatically map memory regions if not configured externally
	if (!has_configured_map(0) && !has_configured_map(1))
	{
		if (m_adpcm_a_region)
			space(0).install_rom(0, m_adpcm_a_region->bytes() - 1, m_adpcm_a_region->base());

		if (m_adpcm_b_region)
			space(1).install_rom(0, m_adpcm_b_region->bytes() - 1, m_adpcm_b_region->base());
		else if (m_adpcm_a_region)
			space(1).install_rom(0, m_adpcm_a_region->bytes() - 1, m_adpcm_a_region->base());
	}
}


//-------------------------------------------------
//  ymfm_external_read - callback to read data for
//  the ADPCM-A/B engines
//-------------------------------------------------

template<typename ChipClass>
uint8_t ym2610_device_base<ChipClass>::ymfm_external_read(ymfm::access_class type, uint32_t offset)
{
	if (type == ymfm::ACCESS_ADPCM_A)
		return space(0).read_byte(offset);
	else if (type == ymfm::ACCESS_ADPCM_B)
		return space(1).read_byte(offset);
	return 0;
}



//*********************************************************
//  YM2610 DEVICE
//*********************************************************

DEFINE_DEVICE_TYPE(YM2610, ym2610_device, "ym2610", "YM2610 OPNB")

//-------------------------------------------------
//  ym2610_device - constructor
//-------------------------------------------------

ym2610_device::ym2610_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	ym2610_device_base<ymfm::ym2610>(mconfig, tag, owner, clock, YM2610)
{
}


//*********************************************************
//  YM2610B DEVICE
//*********************************************************

DEFINE_DEVICE_TYPE(YM2610B, ym2610b_device, "ym2610b", "YM2610B OPNB2")

//-------------------------------------------------
//  ym2610b_device - constructor
//-------------------------------------------------

ym2610b_device::ym2610b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	ym2610_device_base<ymfm::ym2610b>(mconfig, tag, owner, clock, YM2610B)
{
}



//*********************************************************
//  YM2612 DEVICE
//*********************************************************

DEFINE_DEVICE_TYPE(YM2612, ym2612_device, "ym2612", "YM2612 OPN2")

//-------------------------------------------------
//  ym2612_device - constructor
//-------------------------------------------------

ym2612_device::ym2612_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	ymfm_device_base<ymfm::ym2612>(mconfig, tag, owner, clock, YM2612)
{
}



//*********************************************************
//  YM3438 DEVICE
//*********************************************************

DEFINE_DEVICE_TYPE(YM3438, ym3438_device, "ym3438", "YM3438 OPN2C")

//-------------------------------------------------
//  ym3438_device - constructor
//-------------------------------------------------

ym3438_device::ym3438_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	ymfm_device_base<ymfm::ym3438>(mconfig, tag, owner, clock, YM3438)
{
}



//*********************************************************
//  YMF276 DEVICE
//*********************************************************

DEFINE_DEVICE_TYPE(YMF276, ymf276_device, "ymf276", "YMF276 OPN2L")

//-------------------------------------------------
//  ymf276_device - constructor
//-------------------------------------------------

ymf276_device::ymf276_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	ymfm_device_base<ymfm::ymf276>(mconfig, tag, owner, clock, YMF276)
{
}