summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/tms36xx.h
blob: 01fdc22d306c76e3371da710ff2dc50b2d8d068d (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
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
#ifndef MAME_SOUND_TMS36XX_H
#define MAME_SOUND_TMS36XX_H

#pragma once

//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_TMS36XX_ADD(tag, clock) \
	MCFG_DEVICE_ADD((tag), TMS36XX, (clock))

#define MCFG_TMS36XX_REPLACE(tag, clock) \
	MCFG_DEVICE_REPLACE((tag), TMS36XX, (clock))

#define MCFG_TMS36XX_TYPE(type) \
	downcast<tms36xx_device &>(*device).set_subtype((tms36xx_device::subtype::type));

#define MCFG_TMS36XX_DECAY_TIMES(_dec0, _dec1, _dec2, _dec3, _dec4, _dec5) \
	downcast<tms36xx_device &>(*device).set_decays(_dec0, _dec1, _dec2, _dec3, _dec4, _dec5);

#define MCFG_TMS36XX_TUNE_SPEED(_speed) \
	downcast<tms36xx_device &>(*device).set_tune_speed(_speed);


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************



// ======================> tms36xx_device

class tms36xx_device : public device_t,
						public device_sound_interface
{
public:
	enum class subtype
	{
		MM6221AA    = 21,     // Phoenix (fixed melodies)
		TMS3615     = 15,     // Naughty Boy, Pleiads (13 notes, one output)
		TMS3617     = 17      // Monster Bash (13 notes, six outputs)
	};

	tms36xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void set_subtype(subtype type)
	{
		switch (type)
		{
		case subtype::MM6221AA:
			m_subtype = "MM6221AA";
			break;
		case subtype::TMS3615:
			m_subtype = "TMS3615";
			break;
		case subtype::TMS3617:
			m_subtype = "TMS3617";
			break;
		default:
			fatalerror("Invalid TMS36XX type: %d\n", int(type));
			break;
		}
	}
	void set_tune_speed(double speed) { m_speed = (speed > 0) ? TMS36XX_VMAX / speed : TMS36XX_VMAX; }
	void set_decays(double decay_0, double decay_1, double decay_2, double decay_3, double decay_4, double decay_5)
	{
		m_decay_time[0] = decay_0;
		m_decay_time[1] = decay_1;
		m_decay_time[2] = decay_2;
		m_decay_time[3] = decay_3;
		m_decay_time[4] = decay_4;
		m_decay_time[5] = decay_5;
	}

protected:
	static constexpr unsigned TMS36XX_VMIN = 0x0000;
	static constexpr unsigned TMS36XX_VMAX = 0x7fff;

	// device-level overrides
	virtual void device_start() override;

	// sound stream update overrides
	virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;

public:
	// MM6221AA interface functions
	void mm6221aa_tune_w(int tune);

	// TMS3615/17 interface functions
	void tms36xx_note_w(int octave, int note);

	// TMS3617 interface functions
	void tms3617_enable_w(int enable);

private:
	void tms36xx_reset_counters();
	void tms3617_enable(int enable);

	double m_decay_time[6];  // decay times for the six harmonic notes

	const char *m_subtype;      // subtype name MM6221AA, TMS3615 or TMS3617
	sound_stream *m_channel; // returned by stream_create()

	int m_samplerate;     // output sample rate

	int m_basefreq;       // chip's base frequency
	int m_octave;         // octave select of the TMS3615

	int m_speed;          // speed of the tune
	int m_tune_counter;   // tune counter
	int m_note_counter;   // note counter

	int m_voices;         // active voices
	int m_shift;          // shift toggles between 0 and 6 to allow decaying voices
	int m_vol[12];        // (decaying) volume of harmonics notes
	int m_vol_counter[12];// volume adjustment counter
	int m_decay[12];      // volume adjustment rate - derived from m_intf_decay

	int m_counter[12];    // tone frequency counter
	int m_frequency[12];  // tone frequency
	int m_output;         // output signal bits
	int m_enable;         // mask which harmonics

	int m_tune_num;       // tune currently playing
	int m_tune_ofs;       // note currently playing
	int m_tune_max;       // end of tune
};

DECLARE_DEVICE_TYPE(TMS36XX, tms36xx_device)


#endif // MAME_SOUND_TMS36XX_H