summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/segasnd.h
blob: 36dc36cec33d1d1055840ff0ae9a8c34c0c8c987 (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
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************

    Sega g80 common sound hardware

*************************************************************************/

#include "cpu/mcs48/mcs48.h"

class speech_sound_device : public device_t,
									public device_sound_interface
{
public:
	speech_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
	~speech_sound_device() {}

	DECLARE_WRITE8_MEMBER( data_w );
	DECLARE_WRITE8_MEMBER( control_w );

	DECLARE_READ8_MEMBER( t0_r );
	DECLARE_READ8_MEMBER( t1_r );
	DECLARE_READ8_MEMBER( p1_r );
	DECLARE_READ8_MEMBER( rom_r );
	DECLARE_WRITE8_MEMBER( p1_w );
	DECLARE_WRITE8_MEMBER( p2_w );

	static void drq_w(device_t *device, int level);

protected:
	// device-level overrides
	virtual void device_config_complete();
	virtual void device_start();

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

private:
	// internal state
	UINT8 m_drq;
	UINT8 m_latch;
	UINT8 m_t0;
	UINT8 m_p2;
	UINT8 *m_speech;

	TIMER_CALLBACK_MEMBER( delayed_speech_w );
};

extern const device_type SEGASPEECH;

MACHINE_CONFIG_EXTERN( sega_speech_board );




struct filter_state
{
		filter_state():
		capval(0),
		exponent(0) {}

	double              capval;             /* current capacitor value */
	double              exponent;           /* constant exponent */
};


struct timer8253_channel
{
		timer8253_channel():
		holding(0),
		latchmode(0),
		latchtoggle(0),
		clockmode(0),
		bcdmode(0),
		output(0),
		lastgate(0),
		gate(0),
		subcount(0),
		count(0),
		remain(0) {}

	UINT8               holding;            /* holding until counts written? */
	UINT8               latchmode;          /* latching mode */
	UINT8               latchtoggle;        /* latching state */
	UINT8               clockmode;          /* clocking mode */
	UINT8               bcdmode;            /* BCD mode? */
	UINT8               output;             /* current output value */
	UINT8               lastgate;           /* previous gate value */
	UINT8               gate;               /* current gate value */
	UINT8               subcount;           /* subcount (2MHz clocks per input clock) */
	UINT16              count;              /* initial count */
	UINT16              remain;             /* current down counter value */
};


struct timer8253
{
		timer8253()
		{
		env[0] = 0;
		env[1] = 0;
		env[2] = 0;
		config = 0;
		}

	timer8253_channel   chan[3];            /* three channels' worth of information */
	double              env[3];             /* envelope value for each channel */
	filter_state        chan_filter[2];     /* filter states for the first two channels */
	filter_state        gate1;              /* first RC filter state */
	filter_state        gate2;              /* second RC filter state */
	UINT8               config;             /* configuration for this timer */
};


class usb_sound_device : public device_t,
									public device_sound_interface
{
public:
	usb_sound_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
	usb_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
	~usb_sound_device() {}
	required_device<i8035_device> m_ourcpu;                 /* CPU index of the 8035 */

	DECLARE_READ8_MEMBER( status_r );
	DECLARE_WRITE8_MEMBER( data_w );
	DECLARE_READ8_MEMBER( ram_r );
	DECLARE_WRITE8_MEMBER( ram_w );

	DECLARE_READ8_MEMBER( p1_r );
	DECLARE_WRITE8_MEMBER( p1_w );
	DECLARE_WRITE8_MEMBER( p2_w );
	DECLARE_READ8_MEMBER( t1_r );

	DECLARE_READ8_MEMBER( workram_r );
	DECLARE_WRITE8_MEMBER( workram_w );

	TIMER_DEVICE_CALLBACK_MEMBER( increment_t1_clock_timer_cb );

protected:
	// device-level overrides
	virtual machine_config_constructor device_mconfig_additions() const;
	virtual void device_config_complete();
	virtual void device_start();
	virtual void device_reset();

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

private:
	// internal state
	sound_stream        *m_stream;              /* output stream */
	device_t            *m_maincpu;
	UINT8               m_in_latch;             /* input latch */
	UINT8               m_out_latch;            /* output latch */
	UINT8               m_last_p2_value;        /* current P2 output value */
	UINT8 *             m_program_ram;          /* pointer to program RAM */
	UINT8 *             m_work_ram;             /* pointer to work RAM */
	UINT8               m_work_ram_bank;        /* currently selected work RAM bank */
	UINT8               m_t1_clock;             /* T1 clock value */
	UINT8               m_t1_clock_mask;        /* T1 clock mask (configured via jumpers) */
	timer8253           m_timer_group[3];       /* 3 groups of timers */
	UINT8               m_timer_mode[3];        /* mode control for each group */
	UINT32              m_noise_shift;
	UINT8               m_noise_state;
	UINT8               m_noise_subcount;
	double              m_gate_rc1_exp[2];
	double              m_gate_rc2_exp[2];
	filter_state        m_final_filter;
	filter_state        m_noise_filters[5];

	TIMER_CALLBACK_MEMBER( delayed_usb_data_w );
	void timer_w(int which, UINT8 offset, UINT8 data);
	void env_w(int which, UINT8 offset, UINT8 data);
};

extern const device_type SEGAUSB;

class usb_rom_sound_device : public usb_sound_device
{
public:
	usb_rom_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
	~usb_rom_sound_device() {}

protected:
	// device-level overrides
	virtual machine_config_constructor device_mconfig_additions() const;
};

extern const device_type SEGAUSBROM;

#define MCFG_SEGAUSB_ADD(_tag) \
	MCFG_SOUND_ADD(_tag, SEGAUSB, 0) \
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)

	#define MCFG_SEGAUSBROM_ADD(_tag) \
	MCFG_SOUND_ADD(_tag, SEGAUSBROM, 0) \
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)