1 /*
2  * nes_psg.c
3  *
4  * NES sound emulation system
5  */
6 
7 /* $Id: nes_psg.c,v 1.51 2001/03/16 19:56:49 nyef Exp $ */
8 
9 #include "nes_psg.h"
10 #include "snd.h"
11 #include "types.h"
12 
13 /*
14  * sound register data
15  */
16 
17 #ifdef SOUND
18 struct channel { u8 a; u8 b; u8 c; u8 d; };
19 
20 struct channel nes_psg_c1;
21 struct channel nes_psg_c2;
22 struct channel nes_psg_c3;
23 struct channel nes_psg_c4;
24 
25 u8 nes_psg_control;
26 #endif
27 
28 /*
29  * a psg write function is of the form c#$ where # is the channel number and
30  *   $ is the channel register starting from a
31  */
32 
33 #ifdef SOUND
34 #define PSG_WRITEFUNC(channel, reg) \
35 void nes_psg_write_##channel##reg(u8 value) \
36 { \
37     nes_psg_##channel.reg = value; \
38 }
39 #else
40 #define PSG_WRITEFUNC(channel, reg) \
41 void nes_psg_write_##channel##reg(u8 value) \
42 { \
43 }
44 #endif
45 
46 void nes_psg_write_c1d(u8);
47 void nes_psg_write_c2d(u8);
48 void nes_psg_write_c3d(u8);
49 
50 PSG_WRITEFUNC(c1, a); PSG_WRITEFUNC(c1, b); PSG_WRITEFUNC(c1, c);
51 PSG_WRITEFUNC(c2, a); PSG_WRITEFUNC(c2, b); PSG_WRITEFUNC(c2, c);
52 PSG_WRITEFUNC(c3, a); PSG_WRITEFUNC(c3, b); PSG_WRITEFUNC(c3, c);
53 PSG_WRITEFUNC(c4, a); PSG_WRITEFUNC(c4, b); PSG_WRITEFUNC(c4, c);
54 PSG_WRITEFUNC(c4, d);
55 
56 #ifndef SOUND
57 PSG_WRITEFUNC(c1, d);
58 PSG_WRITEFUNC(c2, d);
59 PSG_WRITEFUNC(c3, d);
60 #endif
61 
62 psg_writefunc sound_regs[16] = {
63     nes_psg_write_c1a, nes_psg_write_c1b, nes_psg_write_c1c, nes_psg_write_c1d,
64     nes_psg_write_c2a, nes_psg_write_c2b, nes_psg_write_c2c, nes_psg_write_c2d,
65     nes_psg_write_c3a, nes_psg_write_c3b, nes_psg_write_c3c, nes_psg_write_c3d,
66     nes_psg_write_c4a, nes_psg_write_c4b, nes_psg_write_c4c, nes_psg_write_c4d,
67 };
68 
nes_psg_write_control(u8 value)69 void nes_psg_write_control(u8 value)
70 {
71 #ifdef SOUND
72     nes_psg_control = value;
73 #endif
74 }
75 
76 int nes_psg_quality;
77 
78 #ifdef SOUND
79 /*
80  * Sync occurs every 7467 CPU cycles.
81  * Therefore, at the rate calculated
82  * for 44.1kHz (our highest rate),
83  * there are 182 samples per sync.
84  */
85 static u8 wave_buffers[4][182];
86 
87 unsigned long nes_psg_pulse_magic;
88 unsigned long nes_psg_triangle_magic;
89 unsigned long nes_psg_noise_magic;
90 unsigned int nes_psg_samples_per_sync;
91 unsigned int nes_psg_cycles_per_sample;
92 unsigned int nes_psg_sample_rate;
93 
94 struct nes_psg_quality_data {
95     unsigned long pulse_magic;
96     unsigned long triangle_magic;
97     unsigned long noise_magic;
98     unsigned int samples_per_sync;
99     unsigned int cycles_per_sample;
100     unsigned int sample_rate;
101 } nes_psg_qual[] = {
102     {0xa2567000, 0x512b3800, 0x512b3800,  91, 82, 22050},
103     {0x512b3800, 0x289d9c00, 0x289d9c00, 182, 41, 44100},
104 };
105 
106 /* NOTE: these routines use 8.24 bit fixed point math in places. */
107 
108 /* FIXME: some frequency values are not handled well by this system. */
109 
110 unsigned char pulse_25[0x20] = {
111     0x11, 0x11, 0x11, 0x11,
112     0x11, 0x11, 0x11, 0x11,
113     0x00, 0x00, 0x00, 0x00,
114     0x00, 0x00, 0x00, 0x00,
115     0x00, 0x00, 0x00, 0x00,
116     0x00, 0x00, 0x00, 0x00,
117     0x00, 0x00, 0x00, 0x00,
118     0x00, 0x00, 0x00, 0x00,
119 };
120 
121 unsigned char pulse_50[0x20] = {
122     0x11, 0x11, 0x11, 0x11,
123     0x11, 0x11, 0x11, 0x11,
124     0x11, 0x11, 0x11, 0x11,
125     0x11, 0x11, 0x11, 0x11,
126     0x00, 0x00, 0x00, 0x00,
127     0x00, 0x00, 0x00, 0x00,
128     0x00, 0x00, 0x00, 0x00,
129     0x00, 0x00, 0x00, 0x00,
130 };
131 
132 unsigned char pulse_75[0x20] = {
133     0x11, 0x11, 0x11, 0x11,
134     0x11, 0x11, 0x11, 0x11,
135     0x11, 0x11, 0x11, 0x11,
136     0x11, 0x11, 0x11, 0x11,
137     0x11, 0x11, 0x11, 0x11,
138     0x11, 0x11, 0x11, 0x11,
139     0x00, 0x00, 0x00, 0x00,
140     0x00, 0x00, 0x00, 0x00,
141 };
142 
143 unsigned char pulse_87[0x20] = {
144     0x11, 0x11, 0x11, 0x11,
145     0x11, 0x11, 0x11, 0x11,
146     0x11, 0x11, 0x11, 0x11,
147     0x11, 0x11, 0x11, 0x11,
148     0x11, 0x11, 0x11, 0x11,
149     0x11, 0x11, 0x11, 0x11,
150     0x11, 0x11, 0x11, 0x11,
151     0x00, 0x00, 0x00, 0x00,
152 };
153 
154 unsigned char triangle_50[0x20] = {
155     0x00, 0x11, 0x22, 0x33,
156     0x44, 0x55, 0x66, 0x77,
157     0x88, 0x99, 0xaa, 0xbb,
158     0xcc, 0xdd, 0xee, 0xff,
159     0xff, 0xee, 0xdd, 0xcc,
160     0xbb, 0xaa, 0x99, 0x88,
161     0x77, 0x66, 0x55, 0x44,
162     0x33, 0x22, 0x11, 0x00,
163 };
164 
165 unsigned char *pulse_waves[4] = {
166     pulse_87, pulse_75, pulse_50, pulse_25,
167 };
168 
169 unsigned char nes_psg_atl[0x20] = {
170     5, 127, 10, 1, 20,  2, 40,  3, 80,  4, 30,  5, 7,  6, 13,  7,
171     6,   8, 12, 9, 24, 10, 48, 11, 96, 12, 36, 13, 8, 14, 16, 15,
172 };
173 
174 /*
175  * volume envelopes
176  */
177 
178 struct envelope {
179     u8 decay_counter;
180     u8 rate_counter;
181 };
182 
envelope_get_volume(struct channel * channel,struct envelope * envelope)183 u8 envelope_get_volume(struct channel *channel, struct envelope *envelope)
184 {
185     if (channel->a & 0x10) {
186 	return channel->a & 0x0f;
187     } else {
188 	return envelope->decay_counter;
189     }
190 }
191 
envelope_run_counter(struct channel * channel,struct envelope * envelope)192 void envelope_run_counter(struct channel *channel, struct envelope *envelope)
193 {
194     if (envelope->rate_counter--) return;
195     envelope->rate_counter = channel->a & 0x0f;
196 
197     if (envelope->decay_counter--) return;
198     envelope->decay_counter = (channel->a & 0x20)? 0x0f: 0;
199 }
200 
201 /*
202  * frequency sweeps
203  */
204 
sweep_unit_active(struct channel * channel)205 static int sweep_unit_active(struct channel *channel)
206 {
207     return channel->b & 0x80;
208 }
209 
sweep_unit_shift_count(struct channel * channel)210 static int sweep_unit_shift_count(struct channel *channel)
211 {
212     return channel->b & 7;
213 }
214 
sweep_unit_should_sweep_down(struct channel * channel)215 static int sweep_unit_should_sweep_down(struct channel *channel)
216 {
217     return channel->b & 0x08;
218 }
219 
sweep_unit_set_frequency(struct channel * channel,u16 freq)220 static void sweep_unit_set_frequency(struct channel *channel, u16 freq)
221 {
222     channel->c = freq;
223     channel->d &= ~7;
224     channel->d |= (freq >> 8) & 7;
225 }
226 
sweep_unit_do_sweep(struct channel * channel,u16 freq)227 static void sweep_unit_do_sweep(struct channel *channel, u16 freq)
228 {
229     if (sweep_unit_should_sweep_down(channel)) {
230 	freq -= freq >> sweep_unit_shift_count(channel);
231 	if (channel == &nes_psg_c1) {
232 	    freq--;
233 	}
234     } else {
235 	freq += freq >> sweep_unit_shift_count(channel);
236     }
237 
238     sweep_unit_set_frequency(channel, freq);
239 
240     /* FIXME: sweep unit upper bound shutdown? */
241 }
242 
run_sweep_unit(struct channel * channel,int * sweep_clock,u16 freq)243 void run_sweep_unit(struct channel *channel, int *sweep_clock, u16 freq)
244 {
245     if (!sweep_unit_active(channel)) return;
246 
247     if ((*sweep_clock)--) return;
248     *sweep_clock = (channel->b >> 3) & 0x0e;
249 
250     if (!sweep_unit_shift_count(channel)) return;
251 
252     sweep_unit_do_sweep(channel, freq);
253 }
254 
255 /*
256  * nes_psg_frame is called every 7457 CPU cycles to do sound rendering.
257  */
258 
259 static u32 wave_1_index;
260 static int wave_1_sweep_clock;
261 static u8 wave_1_length_counter;
262 static struct envelope wave_1_envelope;
263 
nes_psg_write_c1d(u8 value)264 void nes_psg_write_c1d(u8 value)
265 {
266     nes_psg_c1.d = value;
267     wave_1_envelope.decay_counter = 0x0f;
268     wave_1_length_counter = nes_psg_atl[value >> 3];
269 }
270 
nes_psg_wave_1(void)271 void nes_psg_wave_1(void)
272 {
273     int i;
274     u8 volume;
275     u16 freq;
276     u32 step;
277     u8 *sample;
278 
279     volume = envelope_get_volume(&nes_psg_c1, &wave_1_envelope);
280 
281     freq = ((nes_psg_c1.d & 0x07) << 8) + nes_psg_c1.c;
282     if (freq >= 8) { /* sweep unit lower bound shutdown */
283 	step = nes_psg_pulse_magic / freq;
284     } else {
285 	step = 0;
286     }
287 
288     if (!wave_1_length_counter) {
289 	step = 0;
290     }
291 
292     if (!(nes_psg_control & 0x01)) { /* channel output enable */
293 	step = 0;
294     }
295 
296     sample = pulse_waves[(nes_psg_c1.a >> 6)];
297 
298     for (i = 0; i < nes_psg_samples_per_sync; i++) {
299 	wave_1_index += step;
300 	wave_1_index &= 0x1fffffff;
301 	wave_buffers[0][i] = sample[wave_1_index >> 24] * volume;
302     }
303 
304     envelope_run_counter(&nes_psg_c1, &wave_1_envelope);
305 
306     run_sweep_unit(&nes_psg_c1, &wave_1_sweep_clock, freq);
307 }
308 
309 static u32 wave_2_index;
310 static int wave_2_sweep_clock;
311 static u8 wave_2_length_counter;
312 static struct envelope wave_2_envelope;
313 
nes_psg_write_c2d(u8 value)314 void nes_psg_write_c2d(u8 value)
315 {
316     nes_psg_c2.d = value;
317     wave_2_envelope.decay_counter = 0x0f;
318     wave_2_length_counter = nes_psg_atl[value >> 3];
319 }
320 
nes_psg_wave_2(void)321 void nes_psg_wave_2(void)
322 {
323     int i;
324     u8 volume;
325     u16 freq;
326     u32 step;
327     u8 *sample;
328 
329     volume = envelope_get_volume(&nes_psg_c2, &wave_2_envelope);
330 
331     freq = ((nes_psg_c2.d & 0x07) << 8) + nes_psg_c2.c;
332     if (freq >= 8) { /* sweep unit lower bound shutdown */
333 	step = nes_psg_pulse_magic / freq;
334     } else {
335 	step = 0;
336     }
337 
338     if (!wave_2_length_counter) {
339 	step = 0;
340     }
341 
342     if (!(nes_psg_control & 0x02)) { /* channel output enable */
343 	step = 0;
344     }
345 
346     sample = pulse_waves[(nes_psg_c2.a >> 6)];
347 
348     for (i = 0; i < nes_psg_samples_per_sync; i++) {
349 	wave_2_index += step;
350 	wave_2_index &= 0x1fffffff;
351 	wave_buffers[1][i] = sample[wave_2_index >> 24] * volume;
352     }
353 
354     envelope_run_counter(&nes_psg_c2, &wave_2_envelope);
355 
356     run_sweep_unit(&nes_psg_c2, &wave_2_sweep_clock, freq);
357 }
358 
359 static u32 wave_3_index;
360 static u8 wave_3_length_counter;
361 
nes_psg_write_c3d(u8 value)362 void nes_psg_write_c3d(u8 value)
363 {
364     nes_psg_c3.d = value;
365     wave_3_length_counter = nes_psg_atl[value >> 3];
366 }
367 
nes_psg_wave_3(void)368 void nes_psg_wave_3(void)
369 {
370     int i;
371     u16 freq;
372     u32 step;
373 
374     /* FIXME: Add linear counter */
375 
376     freq = ((nes_psg_c3.d & 0x07) << 8) + nes_psg_c3.c;
377     if (freq) { /* sweep unit lower bound shutdown */
378 	step = nes_psg_triangle_magic / freq;
379     } else {
380 	step = 0;
381     }
382 
383     if (!wave_3_length_counter) {
384 	step = 0;
385     }
386 
387     if (!(nes_psg_control & 0x04)) { /* channel output enable */
388 	step = 0;
389     }
390 
391     for (i = 0; i < nes_psg_samples_per_sync; i++) {
392 	wave_3_index += step;
393 	wave_3_index &= 0x1fffffff;
394 	wave_buffers[2][i] = triangle_50[wave_3_index >> 24];
395     }
396 }
397 
nes_psg_wave_4(void)398 void nes_psg_wave_4(void)
399 {
400 #if 0
401     int i;
402     int cycles;
403     int event;
404     unsigned char ctrl;
405 
406     ctrl = nes_psg_ctrl;
407 
408     cycles = 0;
409     event = 0;
410 
411     for (i = 0; i < nes_psg_samples_per_sync; i++) {
412 	cycles += nes_psg_cycles_per_sample;
413 	while ((event < cur_event) && (psg_eventqueue[event].time < cycles)) {
414 	    if ((psg_eventqueue[event].type & PSGET_MASK) == PSGET_C4) {
415 		switch (psg_eventqueue[event].type & 3) {
416 		case 0:
417 		    nes_psg_c4a = psg_eventqueue[event].data;
418 		    nes_psg_c4_vol = nes_psg_c4a & 0x0f;
419 		    nes_psg_c4_vol |= nes_psg_c4_vol << 4;
420 /* 		    deb_printf("psg: c4a: vol %d.\n", nes_psg_c4a & 15); */
421 		    break;
422 		case 1:
423 		    nes_psg_c4b = psg_eventqueue[event].data;
424 /* 		    deb_printf("psg: c4b: 0x%02x.\n", nes_psg_c4b); */
425 		    break;
426 		case 2:
427 		    nes_psg_c4c = psg_eventqueue[event].data;
428 		    if (nes_psg_c4c & 0x80) {
429 			nes_psg_c4_sr = 0x001f;
430 		    } else {
431 			nes_psg_c4_sr = 0x01ff;
432 		    }
433 /* 		    if (nes_psg_c4c & 0x70) { */
434 /* 			deb_printf("psg: c4c: c4c & 0x70 == 0x%02x.\n", nes_psg_c4c & 0x70); */
435 /* 		    } */
436 		    if (nes_psg_c4c & 15) {
437 			nes_psg_c4_skip = nes_psg_noise_magic / (nes_psg_c4c & 15);
438 		    } else {
439 			nes_psg_c4_skip = 0;
440 		    }
441 		    nes_psg_c4_atl = nes_psg_atl[(nes_psg_c4d & 0xf8) >> 3];
442 /* 		    deb_printf("psg: c4: freq: %d.\n", nes_psg_c4c & 15); */
443 		    break;
444 		case 3:
445 		    nes_psg_c4d = psg_eventqueue[event].data;
446 		    if (nes_psg_c4c & 15) {
447 			nes_psg_c4_skip = nes_psg_noise_magic / (nes_psg_c4c & 15);
448 		    } else {
449 			nes_psg_c4_skip = 0;
450 		    }
451 		    nes_psg_c4_atl = nes_psg_atl[(nes_psg_c4d & 0xf8) >> 3];
452 		}
453 	    } else if (psg_eventqueue[event].type == PSGET_W_CTRL) {
454 		ctrl = psg_eventqueue[event].data;
455 	    }
456 
457 	    event++;
458 	}
459 	if (ctrl & 8) {
460 	    nes_psg_c4_index += nes_psg_c4_skip;
461 	    if (nes_psg_c4_index > 0x1fffffff) {
462 		if (nes_psg_c4c & 0x80) { /* FIXME: may be wrong */
463 		    nes_psg_c4_sr |= ((!(nes_psg_c4_sr & 1)) ^ (!(nes_psg_c4_sr & 4))) << 5;
464 		} else {
465 		    nes_psg_c4_sr |= ((!(nes_psg_c4_sr & 1)) ^ (!(nes_psg_c4_sr & 16))) << 9;
466 		}
467 		nes_psg_c4_sr >>= 1;
468 	    }
469 	    nes_psg_c4_index &= 0x1fffffff;
470 #if 1
471 	    if (nes_psg_c4_atl && (nes_psg_c4_sr & 1)) {
472 		wave_buffers[3][i] = nes_psg_c4_vol;
473 	    } else {
474 		wave_buffers[3][i] = 0;
475 	    }
476 #else
477 	    wave_buffers[3][i] = 0;
478 #endif
479 	} else {
480 	    wave_buffers[3][i] = 0;
481 	}
482     }
483     if (nes_psg_c4_atl) {
484 	nes_psg_c4_atl--;
485     }
486 
487     nes_psg_ctrl_new = ctrl;
488 #endif
489 }
490 #endif
491 
492 int length_counter_clock;
493 
nes_psg_frame(void)494 void nes_psg_frame(void)
495 {
496 #ifdef SOUND
497     nes_psg_wave_1();
498     nes_psg_wave_2();
499     nes_psg_wave_3();
500     nes_psg_wave_4();
501 
502     if (!length_counter_clock--) {
503 	length_counter_clock = 4; /* FIXME: This may want to be 3 */
504 
505 	if (!(nes_psg_c1.a & 0x20)) {
506 	    if (wave_1_length_counter) {
507 		wave_1_length_counter--;
508 	    }
509 	}
510 
511 	if (!(nes_psg_c2.a & 0x20)) {
512 	    if (wave_2_length_counter) {
513 		wave_2_length_counter--;
514 	    }
515 	}
516 
517 	if (!(nes_psg_c3.a & 0x80)) {
518 	    if (wave_3_length_counter) {
519 		wave_3_length_counter--;
520 	    }
521 	}
522     }
523 
524     snd_output_4_waves(nes_psg_samples_per_sync, wave_buffers[0], wave_buffers[1], wave_buffers[2], wave_buffers[3]);
525 #endif
526 }
527 
nes_psg_init(void)528 void nes_psg_init(void)
529 {
530 #ifdef SOUND
531     snd_init();
532 
533     if (nes_psg_quality > 0) {
534 	if (nes_psg_quality > 2) {
535 	    nes_psg_quality = 1;
536 	} else {
537 	    nes_psg_quality--;
538 	}
539 	nes_psg_pulse_magic = nes_psg_qual[nes_psg_quality].pulse_magic;
540 	nes_psg_triangle_magic = nes_psg_qual[nes_psg_quality].triangle_magic;
541 	nes_psg_noise_magic = nes_psg_qual[nes_psg_quality].noise_magic;
542 	nes_psg_samples_per_sync = nes_psg_qual[nes_psg_quality].samples_per_sync;
543 	nes_psg_cycles_per_sample = nes_psg_qual[nes_psg_quality].cycles_per_sample;
544 	nes_psg_sample_rate = nes_psg_qual[nes_psg_quality].sample_rate;
545 
546 	snd_open(nes_psg_samples_per_sync, nes_psg_sample_rate);
547     } else {
548     }
549 #endif
550 }
551 
nes_psg_done(void)552 void nes_psg_done(void)
553 {
554 #ifdef SOUND
555     snd_close();
556 #endif
557 }
558 
559 /*
560  * $Log: nes_psg.c,v $
561  * Revision 1.51  2001/03/16 19:56:49  nyef
562  * removed a couple unnessecary includes
563  *
564  * Revision 1.50  2000/11/18 14:56:57  nyef
565  * cleaned up envelope_run_counter() and the sweep unit code
566  *
567  * Revision 1.49  2000/10/30 22:24:09  nyef
568  * made wave_buffers[][] static to work around linker bug
569  *
570  * Revision 1.48  2000/10/05 07:57:10  nyef
571  * fixed another "minor" bug triggered when -DSOUND isn't present
572  *
573  * Revision 1.47  2000/10/05 07:52:55  nyef
574  * fixed minor bug with compiling without -DSOUND
575  *
576  * Revision 1.46  2000/10/02 16:35:40  nyef
577  * fixed the sweep unit not to run if the shift count is 0
578  *
579  * Revision 1.45  2000/10/02 16:32:04  nyef
580  * extracted frequency sweep emulation from the pulse wave functions
581  *
582  * Revision 1.44  2000/10/02 16:08:13  nyef
583  * moved volume envelope handling out of nes_psg_wave_?() to new functions
584  *
585  * Revision 1.43  2000/10/02 15:19:50  nyef
586  * halved sweep clock rate (oops)
587  *
588  * Revision 1.42  2000/10/02 14:17:55  nyef
589  * gutted and reimplemented almost everything
590  *
591  * Revision 1.41  2000/05/06 23:25:47  nyef
592  * moved #define SOUND out to the Makefile level
593  *
594  * Revision 1.40  2000/05/06 22:29:11  nyef
595  * fixed to compile with no sound code in the executable
596  *
597  * Revision 1.39  1999/10/31 14:23:53  nyef
598  * fixed to compile with sound disabled
599  *
600  * Revision 1.38  1999/10/31 02:37:28  nyef
601  * broke all os-dependant sound code out to separate files
602  *
603  * Revision 1.37  1999/10/31 00:23:53  nyef
604  * rearranged some stuff in nes_psg_vsync()
605  *
606  * Revision 1.36  1999/10/30 23:58:16  nyef
607  * moved the $4015 handling code from nes_psg_mix() to the wave renderers
608  *
609  * Revision 1.35  1999/08/07 01:05:35  nyef
610  * removed O_NONBLOCK from linux sound open routine
611  * (this should prevent games from going too fast)
612  *
613  * Revision 1.34  1999/07/24 01:36:29  nyef
614  * Fixed noise channel to be far more correct
615  * Enabled noise channel, it's worth it now
616  *
617  * Revision 1.33  1999/02/14 18:27:54  nyef
618  * added a function pointer array for writing the sound regs
619  *
620  * Revision 1.32  1999/01/17 04:21:11  nyef
621  * fixed some problems with disabling sound completely
622  *
623  * Revision 1.31  1998/12/28 04:26:18  nyef
624  * added simple fix for "long note" problem on wave 3.
625  * full volume support on wave 3 is nessecary for proper fix.
626  *
627  * Revision 1.30  1998/12/28 04:10:50  nyef
628  * added disabled preliminary wave 4 generation.
629  *
630  * Revision 1.29  1998/12/27 04:57:34  nyef
631  * added basic framework for wave 4 generation.
632  *
633  * Revision 1.28  1998/12/27 01:57:18  nyef
634  * added support for volume control and looped sounds.
635  *
636  * Revision 1.27  1998/12/17 06:22:19  nyef
637  * cleaned up wave generation functions slightly.
638  *
639  * Revision 1.26  1998/12/12 20:33:07  nyef
640  * commented out "DONT_USE_CAL" as final step in bringing up to spec.
641  *
642  * Revision 1.25  1998/12/12 02:46:42  nyef
643  * fixed bug in nes_psg_open_sound_dos().
644  *
645  * Revision 1.24  1998/12/06 04:15:56  nyef
646  * added preliminary sound quality (playback rate) adjustment.
647  *
648  * Revision 1.23  1998/12/05 23:32:14  nyef
649  * halved the frequency on the triangle waves.
650  *
651  * Revision 1.22  1998/12/05 18:43:03  nyef
652  * active time length counters improved. Dungeon Magic sounds much better.
653  *
654  * Revision 1.21  1998/12/05 18:23:51  nyef
655  * changed from 16.16 fixed point to 8.24 fixed point. Due to some loss of
656  * precision in the conversion, the "sound constant" needs to be recalculated.
657  *
658  * Revision 1.20  1998/12/05 05:25:48  nyef
659  * added pulse wave duty cycles. don't know how well they work.
660  *
661  * Revision 1.19  1998/12/04 02:55:10  nyef
662  * started to bring io write functions up to spec. maintaining backward
663  * compatability for ease of transition and for RockNES.
664  *
665  * Revision 1.18  1998/12/04 02:08:36  nyef
666  * changed wave buffer 'triangle' to 'triangle_50' because allegro already
667  * defines 'triangle'.
668  *
669  * Revision 1.17  1998/12/03 04:58:59  nyef
670  * major overhaul. changed sound rendering method. system sounds a lot
671  * better. channel 3 approaches triangularity for sufficiently large values
672  * of 32. some hooks for duty cycles in place. active time length counters
673  * improved. floating point stuff removed. improved event handling.
674  *
675  * Revision 1.16  1998/12/01 04:01:12  nyef
676  * obtained speedup by storing the value (44100 / 111860.78) * freq in a
677  * local variable instead of calculating it every time it was needed.
678  *
679  * Revision 1.15  1998/12/01 03:34:15  nyef
680  * more doc fixes (mainly adding FIXMEs). added preliminary active time left
681  * support (I don't know if I did it right). more bugfixes.
682  *
683  * Revision 1.14  1998/12/01 02:57:48  nyef
684  * doc fix. removed useless debug code from psg write functions. added
685  * preliminary wave 3 support (needs to be changed to triangle wave).
686  * fixed a few bugs in the wave functions.
687  *
688  * Revision 1.13  1998/11/28 05:06:40  nyef
689  * bashed up linux sound stuff again. reintroduced soundfrags. changed to
690  * use 1024 byte writes with dual local buffers.
691  *
692  * Revision 1.12  1998/11/26 01:39:54  nyef
693  * gratuitous changes. mainly linux latency stuff.
694  *
695  * Revision 1.11  1998/11/05 02:58:31  nyef
696  * added preliminary emulation of psg control register.
697  *
698  * Revision 1.10  1998/11/05 02:29:34  nyef
699  * integrated new dos code changes. sound output now works on dos.
700  *
701  * Revision 1.9  1998/11/04 03:25:45  nyef
702  * moved the code to open the sound device from nes_psg_init() to
703  * nes_psg_open_sound_linux().
704  *
705  * Revision 1.8  1998/11/04 03:20:16  nyef
706  * added (commented out) defines for SOUND_LINUX and SOUND_DOS.
707  * made inclusion of system header files required for compile with
708  * sound support conditional upon definition of SOUND_LINUX.
709  *
710  * Revision 1.7  1998/11/04 03:10:08  nyef
711  * changed all psg event type defines to hexadecimal.
712  * added psg event type PSGET_SYNC.
713  *
714  * Revision 1.6  1998/11/03 00:43:26  nyef
715  * Added preliminary wave 2 generation.
716  *
717  * Revision 1.5  1998/10/21 00:15:33  nyef
718  * commented out the define for sound.
719  * changed some of the debug output in nes_psg_wave_1().
720  *
721  * Revision 1.4  1998/09/19 00:48:25  nyef
722  *   wave 1 generation now working (the video display and rendering must be
723  * disabled for nes_ppu.c for it not to skip on my machine). started
724  * instrumenting wave 1 control regs for furthur insight into wave generation.
725  *
726  * Revision 1.3  1998/09/02 01:25:40  nyef
727  * added test output of wave 1. wave 1 generation still not working.
728  *
729  * Revision 1.2  1998/08/30 20:37:57  nyef
730  * added event queue, filled in the write functions, and added vsync hook.
731  *
732  * Revision 1.1  1998/08/22 00:35:43  nyef
733  * Initial revision
734  *
735  */
736