3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
10 * By Shawn Hargreaves,
16 * Soundblaster driver. Supports DMA driven sample playback (mixing
17 * up to eight samples at a time) and raw note output to the SB MIDI
18 * port. The Adlib (FM synth) MIDI playing code is in adlib.c.
20 * See readme.txt for copyright information.
25 #error This file should only be used by the djgpp version of Allegro
34 #include <sys/farptr.h>
40 /* external interface to the digital SB driver */
41 static int sb_detect();
42 static int sb_init(int voices);
43 static void sb_exit();
44 static int sb_mixer_volume(int volume);
46 static char sb_desc[80] = "not initialised";
53 0, 0, MIXER_MAX_SFX, MIXER_DEF_SFX,
68 _mixer_stop_volume_ramp,
71 _mixer_sweep_frequency,
72 _mixer_stop_frequency_sweep,
76 _mixer_stop_pan_sweep,
83 /* external interface to the SB midi output driver */
84 static int sb_midi_init(int voices);
85 static void sb_midi_exit();
86 static void sb_midi_output(unsigned char data);
88 static char sb_midi_desc[80] = "not initialised";
91 MIDI_DRIVER midi_sb_out =
95 0, 0, 0xFFFF, 0, -1, -1,
102 _dummy_adjust_patches,
112 static int sb_in_use = FALSE; /* is SB being used? */
113 static int sb_stereo = FALSE; /* in stereo mode? */
114 static int sb_16bit = FALSE; /* in 16 bit mode? */
115 static int sb_int = -1; /* interrupt vector */
116 static int sb_dsp_ver = -1; /* SB DSP version */
117 /*static*/ int sb_hw_dsp_ver = -1; /* as reported by autodetect */
118 static int sb_dma_size = -1; /* size of dma transfer in bytes */
119 static int sb_dma_mix_size = -1; /* number of samples to mix */
120 static int sb_dma_count = 0; /* need to resync with dma? */
121 static volatile int sb_semaphore = FALSE; /* reentrant interrupt? */
123 static int sb_sel[2]; /* selectors for the buffers */
124 static unsigned long sb_buf[2]; /* pointers to the two buffers */
125 static int sb_bufnum = 0; /* the one currently in use */
127 static unsigned char sb_default_pic1; /* PIC mask flags to restore */
128 static unsigned char sb_default_pic2;
130 static int sb_master_vol; /* stored mixer settings */
131 static int sb_digi_vol;
132 static int sb_fm_vol;
134 static void sb_lock_mem();
139 * Reads a byte from the SB DSP chip. Returns -1 if it times out.
141 static inline volatile int sb_read_dsp()
145 for (x=0; x<0xffff; x++)
146 if (inportb(0x0E + _sb_port) & 0x80)
147 return inportb(0x0A+_sb_port);
155 * Writes a byte to the SB DSP chip. Returns -1 if it times out.
157 static inline volatile int sb_write_dsp(unsigned char byte)
161 for (x=0; x<0xffff; x++) {
162 if (!(inportb(0x0C+_sb_port) & 0x80)) {
163 outportb(0x0C+_sb_port, byte);
173 * Turns the SB speaker on or off.
175 static void sb_voice(int state)
180 if (sb_hw_dsp_ver >= 0x300) { /* set up the mixer */
182 outportb(_sb_port+4, 0x22); /* store master volume */
183 sb_master_vol = inportb(_sb_port+5);
185 outportb(_sb_port+4, 4); /* store DAC level */
186 sb_digi_vol = inportb(_sb_port+5);
188 outportb(_sb_port+4, 0x26); /* store FM level */
189 sb_fm_vol = inportb(_sb_port+5);
195 if (sb_hw_dsp_ver >= 0x300) { /* reset previous mixer settings */
197 outportb(_sb_port+4, 0x22); /* restore master volume */
198 outportb(_sb_port+5, sb_master_vol);
200 outportb(_sb_port+4, 4); /* restore DAC level */
201 outportb(_sb_port+5, sb_digi_vol);
203 outportb(_sb_port+4, 0x26); /* restore FM level */
204 outportb(_sb_port+5, sb_fm_vol);
212 * Alters the SB-Pro hardware mixer.
214 int _sb_set_mixer(int digi_volume, int midi_volume)
216 if (sb_hw_dsp_ver < 0x300)
219 if (digi_volume >= 0) { /* set DAC level */
220 outportb(_sb_port+4, 4);
221 outportb(_sb_port+5, (digi_volume & 0xF0) | (digi_volume >> 4));
224 if (midi_volume >= 0) { /* set FM level */
225 outportb(_sb_port+4, 0x26);
226 outportb(_sb_port+5, (midi_volume & 0xF0) | (midi_volume >> 4));
235 * Sets the SB mixer volume for playing digital samples.
237 static int sb_mixer_volume(int volume)
239 return _sb_set_mixer(volume, -1);
245 * Enables or disables stereo output for SB-Pro.
247 static void sb_stereo_mode(int enable)
249 outportb(_sb_port+0x04, 0x0E);
250 outportb(_sb_port+0x05, (enable ? 2 : 0));
255 /* sb_set_sample_rate:
256 * The parameter is the rate to set in Hz (samples per second).
258 static void sb_set_sample_rate(unsigned int rate)
262 sb_write_dsp(rate >> 8);
263 sb_write_dsp(rate & 0xff);
270 sb_write_dsp((unsigned char)(256-1000000/rate));
277 * Resets the SB DSP chip, returning -1 on error.
279 static int sb_reset_dsp()
283 outportb(0x06+_sb_port, 1);
286 inportb(0x06+_sb_port);
288 outportb(0x06+_sb_port, 0);
290 if (sb_read_dsp() != 0xAA)
298 /* _sb_read_dsp_version:
299 * Reads the version number of the SB DSP chip, returning -1 on error.
301 int _sb_read_dsp_version()
305 if (sb_hw_dsp_ver > 0)
306 return sb_hw_dsp_ver;
311 if (sb_reset_dsp() != 0)
317 sb_hw_dsp_ver = ((x << 8) | y);
320 return sb_hw_dsp_ver;
326 * Starts a dma transfer of size bytes. On cards capable of it, the
327 * transfer will use auto-initialised dma, so there is no need to call
328 * this routine more than once. On older cards it must be called from
329 * the end-of-buffer handler to switch to the new buffer.
331 static void sb_play_buffer(int size)
333 if (sb_dsp_ver <= 0x200) { /* 8 bit single-shot */
335 sb_write_dsp((size-1) & 0xFF);
336 sb_write_dsp((size-1) >> 8);
338 else if (sb_dsp_ver < 0x400) { /* 8 bit auto-initialised */
340 sb_write_dsp((size-1) & 0xff);
341 sb_write_dsp((size-1) >> 8);
348 sb_write_dsp((size-1) & 0xFF);
349 sb_write_dsp((size-1) >> 8);
353 static END_OF_FUNCTION(sb_play_buffer);
358 * The SB end-of-buffer interrupt handler. Swaps to the other buffer
359 * if the card doesn't have auto-initialised dma, and then refills the
360 * buffer that just finished playing.
362 static int sb_interrupt()
364 if (sb_dsp_ver <= 0x200) { /* not auto-initialised */
365 _dma_start(_sb_dma, sb_buf[1-sb_bufnum], sb_dma_size, FALSE);
366 sb_play_buffer(sb_dma_size);
368 else { /* poll dma position */
370 if (sb_dma_count > 16) {
371 sb_bufnum = (_dma_todo(_sb_dma) > (unsigned)sb_dma_size) ? 1 : 0;
379 ENABLE(); /* mix some more samples */
380 _mix_some_samples(sb_buf[sb_bufnum], _dos_ds, FALSE);
383 sb_semaphore = FALSE;
386 sb_bufnum = 1 - sb_bufnum;
388 if (sb_16bit) /* acknowlege SB */
389 inportb(_sb_port+0x0F);
391 inportb(_sb_port+0x0E);
393 outportb(0x20, 0x20); /* acknowledge interrupt */
394 outportb(0xA0, 0x20);
399 static END_OF_FUNCTION(sb_interrupt);
404 * SB detection routine. Uses the BLASTER environment variable,
405 * or 'sensible' guesses if that doesn't exist.
407 static int sb_detect()
409 char *blaster = getenv("BLASTER");
416 /* what breed of SB are we looking for? */
444 /* parse BLASTER env */
447 while ((*blaster == ' ') || (*blaster == '\t'))
454 _sb_port = strtol(blaster+1, NULL, 16);
459 _sb_irq = strtol(blaster+1, NULL, 10);
460 //added on 11/5/98 by Victor Rachels to hardwire irq 2->9
463 //end this section addition
467 dma8 = strtol(blaster+1, NULL, 10);
471 dma16 = strtol(blaster+1, NULL, 10);
475 while ((*blaster) && (*blaster != ' ') && (*blaster != '\t'))
487 /* make sure we got a good port address */
488 if (sb_reset_dsp() != 0) {
489 static int bases[] = { 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0 };
492 for (i=0; bases[i]; i++) {
494 if (sb_reset_dsp() == 0)
499 /* check if the card really exists */
500 _sb_read_dsp_version();
501 if (sb_hw_dsp_ver < 0) {
502 strcpy(allegro_error, "Sound Blaster not found");
507 sb_dsp_ver = sb_hw_dsp_ver;
509 if (sb_dsp_ver > sb_hw_dsp_ver) {
510 sb_hw_dsp_ver = sb_dsp_ver = -1;
511 strcpy(allegro_error, "Older SB version detected");
516 /* figure out the hardware interrupt number */
518 sb_int = _sb_irq + 104;
520 sb_int = _sb_irq + 8;
522 /* what breed of SB? */
523 if (sb_dsp_ver >= 0x400) {
526 default_freq = 22727;
528 else if (sb_dsp_ver >= 0x300) {
531 default_freq = 22727;
533 else if (sb_dsp_ver >= 0x201) {
536 default_freq = 22727;
538 else if (sb_dsp_ver >= 0x200) {
541 default_freq = 16129;
546 default_freq = 16129;
549 /* set up the playback frequency */
551 _sb_freq = default_freq;
553 if (_sb_freq < 15000) {
557 else if (MIN(_sb_freq, max_freq) < 20000) {
561 else if (MIN(_sb_freq, max_freq) < 40000) {
570 if (sb_dsp_ver <= 0x200)
573 sb_dma_mix_size = sb_dma_size;
575 /* can we handle 16 bit playback? */
576 if (sb_dsp_ver >= 0x400) {
588 /* can we handle stereo? */
589 if (sb_dsp_ver >= 0x300) {
592 sb_dma_mix_size <<= 1;
597 /* set up the card description */
598 sprintf(sb_desc, "%s (%d hz) on port %X, using IRQ %d and DMA channel %d",
599 msg, _sb_freq, _sb_port, _sb_irq, _sb_dma);
607 * SB init routine: returns zero on success, -1 on failure.
609 static int sb_init(int voices)
612 strcpy(allegro_error, "Can't use SB MIDI interface and DSP at the same time");
616 if ((digi_card == DIGI_SB) || (digi_card == DIGI_AUTODETECT)) {
617 if (sb_dsp_ver <= 0x100)
618 digi_card = DIGI_SB10;
619 else if (sb_dsp_ver <= 0x200)
620 digi_card = DIGI_SB15;
621 else if (sb_dsp_ver < 0x300)
622 digi_card = DIGI_SB20;
623 else if (sb_dsp_ver < 0x400)
624 digi_card = DIGI_SBPRO;
626 digi_card = DIGI_SB16;
629 if (sb_dsp_ver <= 0x200) { /* two conventional mem buffers */
630 if ((_dma_allocate_mem(sb_dma_size, &sb_sel[0], &sb_buf[0]) != 0) ||
631 (_dma_allocate_mem(sb_dma_size, &sb_sel[1], &sb_buf[1]) != 0))
634 else { /* auto-init dma, one big buffer */
635 if (_dma_allocate_mem(sb_dma_size*2, &sb_sel[0], &sb_buf[0]) != 0)
638 sb_sel[1] = sb_sel[0];
639 sb_buf[1] = sb_buf[0] + sb_dma_size;
644 digi_sb.voices = voices;
646 if (_mixer_init(sb_dma_mix_size, _sb_freq, sb_stereo, sb_16bit, &digi_sb.voices) != 0)
649 _mix_some_samples(sb_buf[0], _dos_ds, FALSE);
650 _mix_some_samples(sb_buf[1], _dos_ds, FALSE);
653 sb_default_pic1 = inportb(0x21);
654 sb_default_pic2 = inportb(0xA1);
656 if (_sb_irq > 7) { /* enable irq2 and PIC-2 irq */
657 outportb(0x21, sb_default_pic1 & 0xFB);
658 outportb(0xA1, sb_default_pic2 & (~(1<<(_sb_irq-8))));
660 else /* enable PIC-1 irq */
661 outportb(0x21, sb_default_pic1 & (~(1<<_sb_irq)));
663 _install_irq(sb_int, sb_interrupt);
666 sb_set_sample_rate(_sb_freq);
668 if ((sb_hw_dsp_ver >= 0x300) && (sb_dsp_ver < 0x400))
669 sb_stereo_mode(sb_stereo);
671 if (sb_dsp_ver <= 0x200)
672 _dma_start(_sb_dma, sb_buf[0], sb_dma_size, FALSE);
674 _dma_start(_sb_dma, sb_buf[0], sb_dma_size*2, TRUE);
676 sb_play_buffer(sb_dma_size);
685 * SB driver cleanup routine, removes ints, stops dma, frees buffers, etc.
687 static void sb_exit()
689 /* halt sound output */
692 /* stop dma transfer */
695 if (sb_dsp_ver <= 0x0200)
700 /* restore interrupts */
703 /* reset PIC channels */
704 outportb(0x21, sb_default_pic1);
705 outportb(0xA1, sb_default_pic2);
707 /* free conventional memory buffer */
708 __dpmi_free_dos_memory(sb_sel[0]);
709 if (sb_sel[1] != sb_sel[0])
710 __dpmi_free_dos_memory(sb_sel[1]);
714 sb_hw_dsp_ver = sb_dsp_ver = -1;
721 * Initialises the SB midi interface, returning zero on success.
723 static int sb_midi_init(int voices)
726 strcpy(allegro_error, "Can't use SB MIDI interface and DSP at the same time");
734 sprintf(sb_midi_desc, "Sound Blaster MIDI interface on port %X", _sb_port);
743 * Resets the SB midi interface when we are finished.
745 static void sb_midi_exit()
754 * Writes a byte to the SB midi interface.
756 static void sb_midi_output(unsigned char data)
762 static END_OF_FUNCTION(sb_midi_output);
767 * Locks all the memory touched by parts of the SB code that are executed
768 * in an interrupt context.
770 static void sb_lock_mem()
772 LOCK_VARIABLE(digi_sb);
773 LOCK_VARIABLE(midi_sb_out);
774 LOCK_VARIABLE(_sb_freq);
775 LOCK_VARIABLE(_sb_port);
776 LOCK_VARIABLE(_sb_dma);
777 LOCK_VARIABLE(_sb_irq);
778 LOCK_VARIABLE(sb_int);
779 LOCK_VARIABLE(sb_in_use);
780 LOCK_VARIABLE(sb_dsp_ver);
781 LOCK_VARIABLE(sb_hw_dsp_ver);
782 LOCK_VARIABLE(sb_dma_size);
783 LOCK_VARIABLE(sb_dma_mix_size);
784 LOCK_VARIABLE(sb_sel);
785 LOCK_VARIABLE(sb_buf);
786 LOCK_VARIABLE(sb_bufnum);
787 LOCK_VARIABLE(sb_default_pic1);
788 LOCK_VARIABLE(sb_default_pic2);
789 LOCK_VARIABLE(sb_dma_count);
790 LOCK_VARIABLE(sb_semaphore);
791 LOCK_FUNCTION(sb_play_buffer);
792 LOCK_FUNCTION(sb_interrupt);
793 LOCK_FUNCTION(sb_midi_output);