1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 #ifndef MAME_AUDIO_EXIDY440_H
4 #define MAME_AUDIO_EXIDY440_H
5 
6 #pragma once
7 
8 #define EXIDY440_AUDIO_CLOCK    (XTAL(12'979'200) / 4)
9 #define EXIDY440_MC3418_CLOCK   (EXIDY440_AUDIO_CLOCK / 4 / 16)
10 #define EXIDY440_MC3417_CLOCK   (EXIDY440_AUDIO_CLOCK / 4 / 32)
11 
12 
13 class exidy440_sound_device : public device_t, public device_sound_interface
14 {
15 public:
16 	exidy440_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
~exidy440_sound_device()17 	~exidy440_sound_device() {}
18 
19 	void exidy440_sound_command(uint8_t param);
20 	uint8_t exidy440_sound_command_ack();
21 
22 	DECLARE_WRITE_LINE_MEMBER(sound_interrupt_w);
23 	DECLARE_WRITE_LINE_MEMBER(sound_reset_w);
24 
25 protected:
26 	// device-level overrides
27 	virtual void device_add_mconfig(machine_config &config) override;
28 	virtual void device_start() override;
29 	virtual void device_stop() override;
30 
31 	// sound stream update overrides
32 	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
33 
34 private:
35 	void exidy440_audio_map(address_map &map);
36 
37 	/* channel_data structure holds info about each 6844 DMA channel */
38 	struct m6844_channel_data
39 	{
40 		int active;
41 		int address;
42 		int counter;
43 		uint8_t control;
44 		int start_address;
45 		int start_counter;
46 	};
47 
48 
49 	/* channel_data structure holds info about each active sound channel */
50 	struct sound_channel_data
51 	{
52 		int16_t *base;
53 		int offset;
54 		int remaining;
55 	};
56 
57 
58 	/* sound_cache_entry structure contains info on each decoded sample */
59 	struct sound_cache_entry
60 	{
61 		struct sound_cache_entry *next;
62 		int address;
63 		int length;
64 		int bits;
65 		int frequency;
66 		int16_t data[1];
67 	};
68 
69 	required_device<cpu_device> m_audiocpu;
70 	required_region_ptr<uint8_t> m_samples;
71 
72 	// internal state
73 	uint8_t m_sound_command;
74 	uint8_t m_sound_command_ack;
75 
76 	uint8_t m_sound_banks[4];
77 	//uint8_t m_m6844_data[0x20];
78 	uint8_t m_sound_volume[0x10];
79 	std::vector<int32_t> m_mixer_buffer_left;
80 	std::vector<int32_t> m_mixer_buffer_right;
81 	sound_cache_entry *m_sound_cache;
82 	sound_cache_entry *m_sound_cache_end;
83 	sound_cache_entry *m_sound_cache_max;
84 
85 	/* 6844 description */
86 	m6844_channel_data m_m6844_channel[4];
87 	uint8_t m_m6844_priority;
88 	uint8_t m_m6844_interrupt;
89 	uint8_t m_m6844_chain;
90 
91 	/* sound interface parameters */
92 	sound_stream *m_stream;
93 	sound_channel_data m_sound_channel[4];
94 
95 	/* debugging */
96 	FILE *m_debuglog;
97 
98 	/* channel frequency is configurable */
99 	int m_channel_frequency[4];
100 
101 	void m6844_update();
102 	void m6844_finished(m6844_channel_data *channel);
103 	void play_cvsd(int ch);
104 	void stop_cvsd(int ch);
105 
106 	void reset_sound_cache();
107 	int16_t *add_to_sound_cache(uint8_t *input, int address, int length, int bits, int frequency);
108 	int16_t *find_or_add_to_sound_cache(int address, int length, int bits, int frequency);
109 
110 	void decode_and_filter_cvsd(uint8_t *data, int bytes, int maskbits, int frequency, int16_t *dest);
111 	void fir_filter(int32_t *input, int16_t *output, int count);
112 
113 	void add_and_scale_samples(int ch, int32_t *dest, int samples, int volume);
114 	void mix_to_16(write_stream_view &dest_left, write_stream_view &dest_right);
115 
116 	uint8_t sound_command_r();
117 	uint8_t sound_volume_r(offs_t offset);
118 	void sound_volume_w(offs_t offset, uint8_t data);
119 	void sound_interrupt_clear_w(uint8_t data);
120 	uint8_t m6844_r(offs_t offset);
121 	void m6844_w(offs_t offset, uint8_t data);
122 	void sound_banks_w(offs_t offset, uint8_t data);
123 };
124 
125 DECLARE_DEVICE_TYPE(EXIDY440, exidy440_sound_device)
126 
127 
128 #endif // MAME_AUDIO_EXIDY440_H
129