1 // license:BSD-3-Clause
2 // copyright-holders:Anthony Kruize, Wilbert Pol
3 // thanks-to:Shay Green
4 #ifndef MAME_SOUND_GB_H
5 #define MAME_SOUND_GB_H
6 
7 
8 class gameboy_sound_device : public device_t,
9 							public device_sound_interface
10 {
11 public:
12 	gameboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
13 
14 	u8 sound_r(offs_t offset);
15 	virtual u8 wave_r(offs_t offset) = 0;
16 	virtual void sound_w(offs_t offset, u8 data) = 0;
17 	virtual void wave_w(offs_t offset, u8 data) = 0;
18 
19 protected:
20 	gameboy_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
21 
22 	// device-level overrides
23 	virtual void device_start() override;
24 	virtual void device_clock_changed() override;
25 	virtual void device_reset() override;
26 
27 	// sound stream update overrides
28 	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
29 
30 protected:
31 	enum
32 	{
33 		NR10 = 0x00,
34 		NR11 = 0x01,
35 		NR12 = 0x02,
36 		NR13 = 0x03,
37 		NR14 = 0x04,
38 		// 0x05
39 		NR21 = 0x06,
40 		NR22 = 0x07,
41 		NR23 = 0x08,
42 		NR24 = 0x09,
43 		NR30 = 0x0A,
44 		NR31 = 0x0B,
45 		NR32 = 0x0C,
46 		NR33 = 0x0D,
47 		NR34 = 0x0E,
48 		// 0x0F
49 		NR41 = 0x10,
50 		NR42 = 0x11,
51 		NR43 = 0x12,
52 		NR44 = 0x13,
53 		NR50 = 0x14,
54 		NR51 = 0x15,
55 		NR52 = 0x16,
56 		// 0x17 - 0x1F
57 		AUD3W0 = 0x20,
58 		AUD3W1 = 0x21,
59 		AUD3W2 = 0x22,
60 		AUD3W3 = 0x23,
61 		AUD3W4 = 0x24,
62 		AUD3W5 = 0x25,
63 		AUD3W6 = 0x26,
64 		AUD3W7 = 0x27,
65 		AUD3W8 = 0x28,
66 		AUD3W9 = 0x29,
67 		AUD3WA = 0x2A,
68 		AUD3WB = 0x2B,
69 		AUD3WC = 0x2C,
70 		AUD3WD = 0x2D,
71 		AUD3WE = 0x2E,
72 		AUD3WF = 0x2F
73 	};
74 
75 	static const unsigned int FRAME_CYCLES = 8192;
76 	static const int wave_duty_table[4][8];
77 
78 	sound_stream *m_channel;
79 
80 	struct SOUND
81 	{
82 		/* Common */
83 		uint8_t  reg[5];
84 		bool   on;
85 		uint8_t  channel;
86 		uint8_t  length;
87 		uint8_t  length_mask;
88 		bool   length_counting;
89 		bool   length_enabled;
90 		/* Mode 1, 2, 3 */
91 		uint64_t cycles_left;
92 		int8_t   duty;
93 		/* Mode 1, 2, 4 */
94 		bool   envelope_enabled;
95 		int8_t   envelope_value;
96 		int8_t   envelope_direction;
97 		uint8_t  envelope_time;
98 		uint8_t  envelope_count;
99 		int8_t   signal;
100 		/* Mode 1 */
101 		uint16_t frequency;
102 		uint16_t frequency_counter;
103 		bool   sweep_enabled;
104 		bool   sweep_neg_mode_used;
105 		uint8_t  sweep_shift;
106 		int32_t  sweep_direction;
107 		uint8_t  sweep_time;
108 		uint8_t  sweep_count;
109 		/* Mode 3 */
110 		uint8_t  level;
111 		uint8_t  offset;
112 		uint32_t duty_count;
113 		int8_t   current_sample;
114 		bool   sample_reading;
115 		/* Mode 4 */
116 		bool   noise_short;
117 		uint16_t noise_lfsr;
118 	};
119 
120 	struct SOUND  m_snd_1;
121 	struct SOUND  m_snd_2;
122 	struct SOUND  m_snd_3;
123 	struct SOUND  m_snd_4;
124 
125 	struct
126 	{
127 		uint8_t on;
128 		uint8_t vol_left;
129 		uint8_t vol_right;
130 		uint8_t mode1_left;
131 		uint8_t mode1_right;
132 		uint8_t mode2_left;
133 		uint8_t mode2_right;
134 		uint8_t mode3_left;
135 		uint8_t mode3_right;
136 		uint8_t mode4_left;
137 		uint8_t mode4_right;
138 		uint64_t cycles;
139 		bool wave_ram_locked;
140 	} m_snd_control;
141 
142 	uint8_t m_snd_regs[0x30];
143 	attotime m_last_updated;
144 	emu_timer *m_timer;
145 
146 	virtual void apu_power_off() = 0;
147 	void sound_w_internal(int offset, uint8_t data);
148 	void update_square_channel(struct SOUND &snd, uint64_t cycles);
149 	virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) = 0;
150 	void update_noise_channel(struct SOUND &snd, uint64_t cycles);
151 	int32_t calculate_next_sweep(struct SOUND &snd);
152 	void apply_next_sweep(struct SOUND &snd);
153 	void tick_length(struct SOUND &snd);
154 	void tick_sweep(struct SOUND &snd);
155 	void tick_envelope(struct SOUND &snd);
156 	void update_state();
157 	bool dac_enabled(struct SOUND &snd);
corrupt_wave_ram()158 	virtual void corrupt_wave_ram() { };
159 	uint64_t noise_period_cycles();
160 	TIMER_CALLBACK_MEMBER(timer_callback);
161 };
162 
163 
164 class dmg_apu_device : public gameboy_sound_device
165 {
166 public:
167 	dmg_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
168 
169 	virtual u8 wave_r(offs_t offset) override;
170 	virtual void wave_w(offs_t offset, u8 data) override;
171 	virtual void sound_w(offs_t offset, u8 data) override;
172 
173 protected:
174 	virtual void apu_power_off() override;
175 	virtual void corrupt_wave_ram() override;
176 	virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override;
177 };
178 
179 
180 class cgb04_apu_device : public gameboy_sound_device
181 {
182 public:
183 	cgb04_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
184 
185 	virtual u8 wave_r(offs_t offset) override;
186 	virtual void wave_w(offs_t offset, u8 data) override;
187 	virtual void sound_w(offs_t offset, u8 data) override;
188 
189 protected:
190 	virtual void device_reset() override;
191 	virtual void apu_power_off() override;
192 	virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override;
193 };
194 
195 
196 DECLARE_DEVICE_TYPE(DMG_APU, dmg_apu_device)
197 //DECLARE_DEVICE_TYPE(CGB02_APU, cgb02_apu_device)
198 DECLARE_DEVICE_TYPE(CGB04_APU, cgb04_apu_device)
199 //DECLARE_DEVICE_TYPE(CGB05_APU, cgb05_apu_device)
200 
201 #endif // MAME_SOUND_GB_H
202