1 #include <stdlib.h>
2 #include <audio.h>
3 #include <bitops.h>
4 #include <clock.h>
5 #include <controller.h>
6 #include <port.h>
7 
8 /* Controller definitions */
9 #define INTERNAL_DIVIDER	16
10 #define NUM_CHANNELS		4
11 #define NUM_TONE_CHANNELS	3
12 #define NOISE_CHANNEL		3
13 #define LATCH_DATA_CMD_TYPE	1
14 #define DATA_CMD_TYPE		0
15 #define LATCH_VOLUME_CMD_TYPE	1
16 #define LATCH_TONE_CMD_TYPE	0
17 #define MAX_ATTENUATION		0x0F
18 #define MAX_VOLUME		0xFF
19 #define WHITE_NOISE		1
20 #define PERIODIC_NOISE		0
21 #define TAP_MASK		0x09
22 
23 union volume_register {
24 	uint8_t raw;
25 	struct {
26 		uint8_t attenuation:4;
27 		uint8_t reserved:4;
28 	};
29 };
30 
31 union tone_register {
32 	uint16_t raw;
33 	struct {
34 		uint16_t reset_value:10;
35 		uint16_t reserved:6;
36 	};
37 };
38 
39 union noise_register {
40 	uint8_t raw;
41 	struct {
42 		uint8_t shift_rate:2;
43 		uint8_t mode:1;
44 		uint8_t reserved:5;
45 	};
46 };
47 
48 struct channel {
49 	struct {
50 		uint16_t counter:10;
51 		uint16_t unused:6;
52 	};
53 	bool bit;
54 	bool output;
55 };
56 
57 struct latch_data_cmd {
58 	uint8_t data:4;
59 	uint8_t type:1;
60 	uint8_t channel:2;
61 	uint8_t unused:1;
62 };
63 
64 struct data_cmd {
65 	uint8_t data:6;
66 	uint8_t unused:2;
67 };
68 
69 union command {
70 	uint8_t raw;
71 	union {
72 		struct {
73 			uint8_t contents:7;
74 			uint8_t cmd_type:1;
75 		};
76 		struct latch_data_cmd latch_data_cmd;
77 		struct data_cmd data_cmd;
78 	};
79 };
80 
81 struct sn76489 {
82 	union volume_register vol_regs[NUM_CHANNELS];
83 	union tone_register tone_regs[NUM_TONE_CHANNELS];
84 	union noise_register noise_reg;
85 	struct channel channels[NUM_CHANNELS];
86 	uint16_t lfsr;
87 	uint8_t current_reg_type;
88 	uint8_t current_channel;
89 	struct port_region region;
90 	struct clock clock;
91 };
92 
93 static bool sn76489_init(struct controller_instance *instance);
94 static void sn76489_reset(struct controller_instance *instance);
95 static void sn76489_deinit(struct controller_instance *instance);
96 static void sn76489_write(struct sn76489 *sn76489, uint8_t b);
97 static void handle_tone_channel(struct sn76489 *sn76489, int channel);
98 static void handle_noise_channel(struct sn76489 *sn76489);
99 static void mix(struct sn76489 *sn76489);
100 static void sn76489_tick(struct sn76489 *sn76489);
101 
102 static struct pops sn76489_pops = {
103 	.write = (write_t)sn76489_write
104 };
105 
sn76489_write(struct sn76489 * sn76489,uint8_t b)106 void sn76489_write(struct sn76489 *sn76489, uint8_t b)
107 {
108 	union command cmd;
109 	uint8_t channel;
110 
111 	/* Fill command parameters */
112 	cmd.raw = b;
113 
114 	/* Handle LATCH/DATA command */
115 	if (cmd.cmd_type == LATCH_DATA_CMD_TYPE) {
116 		/* Extract channel */
117 		channel = cmd.latch_data_cmd.channel;
118 
119 		/* The 4 data bits are placed into the low 4 bits of the
120 		relevant register. For the three-bit noise register, the highest
121 		bit is discarded. */
122 		if (cmd.latch_data_cmd.type == LATCH_VOLUME_CMD_TYPE)
123 			bitops_setb(&sn76489->vol_regs[channel].raw,
124 				0,
125 				4,
126 				cmd.latch_data_cmd.data);
127 		else if (channel != NOISE_CHANNEL)
128 			bitops_setw(&sn76489->tone_regs[channel].raw,
129 				0,
130 				4,
131 				cmd.latch_data_cmd.data);
132 		else
133 			bitops_setb(&sn76489->noise_reg.raw,
134 				0,
135 				3,
136 				cmd.latch_data_cmd.data);
137 
138 		/* Save register type and channel */
139 		sn76489->current_reg_type = cmd.latch_data_cmd.type;
140 		sn76489->current_channel = channel;
141 	}
142 
143 	/* Handle DATA command */
144 	if (cmd.cmd_type == DATA_CMD_TYPE) {
145 		/* Get latched channel */
146 		channel = sn76489->current_channel;
147 
148 		/* If the currently latched register is a tone register then the
149 		low 6 bits of the byte are placed into the high 6 bits of the
150 		latched register. If the currently latched register is a tone
151 		register then the low 6 bits of the byte are placed into the
152 		high 6 bits of the latched register. */
153 		if (sn76489->current_reg_type == LATCH_VOLUME_CMD_TYPE)
154 			bitops_setb(&sn76489->vol_regs[channel].raw,
155 				0,
156 				4,
157 				cmd.data_cmd.data);
158 		else if (channel != NOISE_CHANNEL)
159 			bitops_setw(&sn76489->tone_regs[channel].raw,
160 				4,
161 				6,
162 				cmd.data_cmd.data);
163 		else
164 			bitops_setb(&sn76489->noise_reg.raw,
165 				0,
166 				4,
167 				cmd.data_cmd.data);
168 	}
169 
170 	/* Reset shift register if needed */
171 	if ((sn76489->current_reg_type == LATCH_TONE_CMD_TYPE) &&
172 		(channel == NOISE_CHANNEL)) {
173 		sn76489->lfsr = 0;
174 		bitops_setw(&sn76489->lfsr, 15, 1, 1);
175 	}
176 }
177 
handle_tone_channel(struct sn76489 * sn76489,int channel)178 void handle_tone_channel(struct sn76489 *sn76489, int channel)
179 {
180 	uint16_t counter;
181 
182 	/* The counter is reset to the value currently in the corresponding
183 	register (eg. Tone0 for channel 0). */
184 	counter = sn76489->tone_regs[channel].reset_value;
185 	sn76489->channels[channel].counter = counter;
186 
187 	/* If the register value is zero or one then the output is a constant
188 	value of +1. This is often used for sample playback. */
189 	if ((counter == 0) || (counter == 1)) {
190 		sn76489->channels[channel].bit = true;
191 		sn76489->channels[channel].output = true;
192 		return;
193 	}
194 
195 	/* The output bit is flipped - if it is currently outputting 1, it
196 	changes to 0, and vice versa. */
197 	sn76489->channels[channel].bit = !sn76489->channels[channel].bit;
198 	sn76489->channels[channel].output = sn76489->channels[channel].bit;
199 }
200 
handle_noise_channel(struct sn76489 * sn76489)201 void handle_noise_channel(struct sn76489 *sn76489)
202 {
203 	struct channel *channel = &sn76489->channels[NOISE_CHANNEL];
204 	bool bit;
205 
206 	/* Reset counter according to the low 2 bits of the noise register */
207 	switch (sn76489->noise_reg.shift_rate) {
208 	case 0x00:
209 		channel->counter = 0x10;
210 		break;
211 	case 0x01:
212 		channel->counter = 0x20;
213 		break;
214 	case 0x02:
215 		channel->counter = 0x40;
216 		break;
217 	case 0x03:
218 		channel->counter = sn76489->tone_regs[2].reset_value;
219 		break;
220 	}
221 
222 	/* As with the tone channels, the output bit is toggled between 0 and 1.
223 	However, this is not sent to the mixer, but to a "linear feedback shift
224 	register" (LFSR), which can generate noise or act as a divider. */
225 	channel->bit = !channel->bit;
226 
227 	/* Handle LFSR only when input changes from 0 to 1 */
228 	if (!channel->bit)
229 		return;
230 
231 	/* Handle white or periodic noise depending on mode */
232 	if (sn76489->noise_reg.mode == WHITE_NOISE) {
233 		/* The input bit is determined by an XOR feedback network.
234 		Certain bits are used as inputs to the XOR gates; these are the
235 		"tapped" bits. */
236 		bit = bitops_parity(sn76489->lfsr & TAP_MASK);
237 	} else {
238 		/* Bit 0 is tapped (the output bit is also the input bit) */
239 		bit = bitops_getw(&sn76489->lfsr, 0, 1);
240 	}
241 
242 	/* Output bit 0 to the mixer */
243 	channel->output = bitops_getw(&sn76489->lfsr, 0, 1);
244 
245 	/* Shift array by one bit and add input bit */
246 	sn76489->lfsr >>= 1;
247 	bitops_setw(&sn76489->lfsr, 15, 1, bit);
248 }
249 
mix(struct sn76489 * sn76489)250 void mix(struct sn76489 *sn76489)
251 {
252 	uint8_t vol;
253 	uint8_t att;
254 	uint8_t final_volume;
255 	int channel;
256 
257 	/* The mixer multiplies each channel's output by the corresponding
258 	volume (or, equivalently, applies the corresponding attenuation), and
259 	sums them. */
260 	final_volume = 0;
261 	for (channel = 0; channel < NUM_CHANNELS; channel++) {
262 		/* Skip channel if needed */
263 		if (!sn76489->channels[channel].output)
264 			continue;
265 
266 		/* Set volume based on attenuation */
267 		att = sn76489->vol_regs[channel].attenuation;
268 		vol = MAX_VOLUME * (MAX_ATTENUATION - att) / MAX_ATTENUATION;
269 
270 		/* Add channel output */
271 		final_volume += vol / NUM_CHANNELS;
272 	};
273 
274 	/* Enqueue mixer output */
275 	audio_enqueue(&final_volume, 1);
276 }
277 
sn76489_tick(struct sn76489 * sn76489)278 void sn76489_tick(struct sn76489 *sn76489)
279 {
280 	int channel;
281 
282 	/* Cycle through channels */
283 	for (channel = 0; channel < NUM_CHANNELS; channel++) {
284 		/* Decrement channel counter if non-zero */
285 		if (sn76489->channels[channel].counter > 0)
286 			sn76489->channels[channel].counter--;
287 
288 		/* Skip channel if counter is still non-zero */
289 		if (sn76489->channels[channel].counter != 0)
290 			continue;
291 
292 		/* Handle tone channel */
293 		if (channel != NOISE_CHANNEL)
294 			handle_tone_channel(sn76489, channel);
295 		else
296 			handle_noise_channel(sn76489);
297 	}
298 
299 	/* Mix all channels */
300 	mix(sn76489);
301 
302 	/* Always consume a single cycle */
303 	clock_consume(1);
304 }
305 
sn76489_init(struct controller_instance * instance)306 bool sn76489_init(struct controller_instance *instance)
307 {
308 	struct sn76489 *sn76489;
309 	struct audio_specs audio_specs;
310 	struct resource *res;
311 
312 	/* Allocate SN76489 structure */
313 	instance->priv_data = calloc(1, sizeof(struct sn76489));
314 	sn76489 = instance->priv_data;
315 
316 	/* Set up port region */
317 	res = resource_get("port",
318 		RESOURCE_PORT,
319 		instance->resources,
320 		instance->num_resources);
321 	sn76489->region.area = res;
322 	sn76489->region.pops = &sn76489_pops;
323 	sn76489->region.data = sn76489;
324 	port_region_add(&sn76489->region);
325 
326 	/* Add clock */
327 	res = resource_get("clk",
328 		RESOURCE_CLK,
329 		instance->resources,
330 		instance->num_resources);
331 	sn76489->clock.rate = res->data.clk / INTERNAL_DIVIDER;
332 	sn76489->clock.data = sn76489;
333 	sn76489->clock.tick = (clock_tick_t)sn76489_tick;
334 	sn76489->clock.enabled = true;
335 	clock_add(&sn76489->clock);
336 
337 	/* Initialize audio frontend */
338 	audio_specs.freq = sn76489->clock.rate;
339 	audio_specs.format = AUDIO_FORMAT_U8;
340 	audio_specs.channels = 1;
341 	if (!audio_init(&audio_specs)) {
342 		free(sn76489);
343 		return false;
344 	}
345 
346 	return true;
347 }
348 
sn76489_reset(struct controller_instance * instance)349 void sn76489_reset(struct controller_instance *instance)
350 {
351 	struct sn76489 *sn76489 = instance->priv_data;
352 	int channel;
353 
354 	/* Reset all attenuations and channel counters */
355 	for (channel = 0; channel < NUM_CHANNELS; channel++) {
356 		sn76489->vol_regs[channel].attenuation = MAX_ATTENUATION;
357 		sn76489->channels[channel].counter = 0;
358 	}
359 }
360 
sn76489_deinit(struct controller_instance * instance)361 void sn76489_deinit(struct controller_instance *instance)
362 {
363 	audio_deinit();
364 	free(instance->priv_data);
365 }
366 
367 CONTROLLER_START(sn76489)
368 	.init = sn76489_init,
369 	.reset = sn76489_reset,
370 	.deinit = sn76489_deinit
371 CONTROLLER_END
372 
373