]> icculus.org git repositories - btb/d2x.git/blob - arch/dos/allg_snd/sound/drv/sb.c
Import of d2x-0.0.8
[btb/d2x.git] / arch / dos / allg_snd / sound / drv / sb.c
1 /*         ______   ___    ___ 
2  *        /\  _  \ /\_ \  /\_ \ 
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___ 
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *      By Shawn Hargreaves,
11  *      1 Salisbury Road,
12  *      Market Drayton,
13  *      Shropshire,
14  *      England, TF9 1AJ.
15  *
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.
19  *
20  *      See readme.txt for copyright information.
21  */
22
23
24 #ifndef DJGPP
25 #error This file should only be used by the djgpp version of Allegro
26 #endif
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <dos.h>
31 #include <go32.h>
32 #include <dpmi.h>
33 #include <limits.h>
34 #include <sys/farptr.h>
35
36 #include "allegro.h"
37 #include "internal.h"
38
39
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);
45
46 static char sb_desc[80] = "not initialised";
47
48
49 DIGI_DRIVER digi_sb =
50 {
51    "Sound Blaster", 
52    sb_desc,
53    0, 0, MIXER_MAX_SFX, MIXER_DEF_SFX,
54    sb_detect,
55    sb_init,
56    sb_exit,
57    sb_mixer_volume,
58    _mixer_init_voice,
59    _mixer_release_voice,
60    _mixer_start_voice,
61    _mixer_stop_voice,
62    _mixer_loop_voice,
63    _mixer_get_position,
64    _mixer_set_position,
65    _mixer_get_volume,
66    _mixer_set_volume,
67    _mixer_ramp_volume,
68    _mixer_stop_volume_ramp,
69    _mixer_get_frequency,
70    _mixer_set_frequency,
71    _mixer_sweep_frequency,
72    _mixer_stop_frequency_sweep,
73    _mixer_get_pan,
74    _mixer_set_pan,
75    _mixer_sweep_pan,
76    _mixer_stop_pan_sweep,
77    _mixer_set_echo,
78    _mixer_set_tremolo,
79    _mixer_set_vibrato
80 };
81
82
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);
87
88 static char sb_midi_desc[80] = "not initialised";
89
90
91 MIDI_DRIVER midi_sb_out =
92 {
93    "SB MIDI interface", 
94    sb_midi_desc,
95    0, 0, 0xFFFF, 0, -1, -1,
96    sb_detect,
97    sb_midi_init,
98    sb_midi_exit,
99    NULL,
100    sb_midi_output,
101    _dummy_load_patches,
102    _dummy_adjust_patches,
103    _dummy_key_on,
104    _dummy_noop1,
105    _dummy_noop2,
106    _dummy_noop3,
107    _dummy_noop2,
108    _dummy_noop2
109 };
110
111
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? */
122
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 */
126
127 static unsigned char sb_default_pic1;     /* PIC mask flags to restore */
128 static unsigned char sb_default_pic2;
129
130 static int sb_master_vol;                 /* stored mixer settings */
131 static int sb_digi_vol;
132 static int sb_fm_vol;
133
134 static void sb_lock_mem();
135
136
137
138 /* sb_read_dsp:
139  *  Reads a byte from the SB DSP chip. Returns -1 if it times out.
140  */
141 static inline volatile int sb_read_dsp()
142 {
143    int x;
144
145    for (x=0; x<0xffff; x++)
146       if (inportb(0x0E + _sb_port) & 0x80)
147          return inportb(0x0A+_sb_port);
148
149    return -1; 
150 }
151
152
153
154 /* sb_write_dsp:
155  *  Writes a byte to the SB DSP chip. Returns -1 if it times out.
156  */
157 static inline volatile int sb_write_dsp(unsigned char byte)
158 {
159    int x;
160
161    for (x=0; x<0xffff; x++) {
162       if (!(inportb(0x0C+_sb_port) & 0x80)) {
163          outportb(0x0C+_sb_port, byte);
164          return 0;
165       }
166    }
167    return -1; 
168 }
169
170
171
172 /* sb_voice:
173  *  Turns the SB speaker on or off.
174  */
175 static void sb_voice(int state)
176 {
177    if (state) {
178       sb_write_dsp(0xD1);
179
180       if (sb_hw_dsp_ver >= 0x300) {       /* set up the mixer */
181
182          outportb(_sb_port+4, 0x22);      /* store master volume */
183          sb_master_vol = inportb(_sb_port+5);
184
185          outportb(_sb_port+4, 4);         /* store DAC level */
186          sb_digi_vol = inportb(_sb_port+5);
187
188          outportb(_sb_port+4, 0x26);      /* store FM level */
189          sb_fm_vol = inportb(_sb_port+5);
190       }
191    }
192    else {
193       sb_write_dsp(0xD3);
194
195       if (sb_hw_dsp_ver >= 0x300) {       /* reset previous mixer settings */
196
197          outportb(_sb_port+4, 0x22);      /* restore master volume */
198          outportb(_sb_port+5, sb_master_vol);
199
200          outportb(_sb_port+4, 4);         /* restore DAC level */
201          outportb(_sb_port+5, sb_digi_vol);
202
203          outportb(_sb_port+4, 0x26);      /* restore FM level */
204          outportb(_sb_port+5, sb_fm_vol);
205       }
206    }
207 }
208
209
210
211 /* _sb_set_mixer:
212  *  Alters the SB-Pro hardware mixer.
213  */
214 int _sb_set_mixer(int digi_volume, int midi_volume)
215 {
216    if (sb_hw_dsp_ver < 0x300)
217       return -1;
218
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));
222    }
223
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));
227    }
228
229    return 0;
230 }
231
232
233
234 /* sb_mixer_volume:
235  *  Sets the SB mixer volume for playing digital samples.
236  */
237 static int sb_mixer_volume(int volume)
238 {
239    return _sb_set_mixer(volume, -1);
240 }
241
242
243
244 /* sb_stereo_mode:
245  *  Enables or disables stereo output for SB-Pro.
246  */
247 static void sb_stereo_mode(int enable)
248 {
249    outportb(_sb_port+0x04, 0x0E); 
250    outportb(_sb_port+0x05, (enable ? 2 : 0));
251 }
252
253
254
255 /* sb_set_sample_rate:
256  *  The parameter is the rate to set in Hz (samples per second).
257  */
258 static void sb_set_sample_rate(unsigned int rate)
259 {
260    if (sb_16bit) {
261       sb_write_dsp(0x41);
262       sb_write_dsp(rate >> 8);
263       sb_write_dsp(rate & 0xff);
264    }
265    else {
266       if (sb_stereo)
267          rate *= 2;
268
269       sb_write_dsp(0x40);
270       sb_write_dsp((unsigned char)(256-1000000/rate));
271    }
272 }
273
274
275
276 /* sb_reset_dsp:
277  *  Resets the SB DSP chip, returning -1 on error.
278  */
279 static int sb_reset_dsp()
280 {
281    int x;
282
283    outportb(0x06+_sb_port, 1);
284
285    for (x=0; x<8; x++)
286       inportb(0x06+_sb_port);
287
288    outportb(0x06+_sb_port, 0);
289
290    if (sb_read_dsp() != 0xAA)
291       return -1;
292
293    return 0;
294 }
295
296
297
298 /* _sb_read_dsp_version:
299  *  Reads the version number of the SB DSP chip, returning -1 on error.
300  */
301 int _sb_read_dsp_version()
302 {
303    int x, y;
304
305    if (sb_hw_dsp_ver > 0)
306       return sb_hw_dsp_ver;
307
308    if (_sb_port <= 0)
309       _sb_port = 0x220;
310
311    if (sb_reset_dsp() != 0)
312       sb_hw_dsp_ver = -1;
313    else {
314       sb_write_dsp(0xE1);
315       x = sb_read_dsp();
316       y = sb_read_dsp();
317       sb_hw_dsp_ver = ((x << 8) | y);
318    }
319
320    return sb_hw_dsp_ver;
321 }
322
323
324
325 /* sb_play_buffer:
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.
330  */
331 static void sb_play_buffer(int size)
332 {
333    if (sb_dsp_ver <= 0x200) {                /* 8 bit single-shot */
334       sb_write_dsp(0x14);
335       sb_write_dsp((size-1) & 0xFF);
336       sb_write_dsp((size-1) >> 8);
337    }
338    else if (sb_dsp_ver < 0x400) {            /* 8 bit auto-initialised */
339       sb_write_dsp(0x48);
340       sb_write_dsp((size-1) & 0xff);
341       sb_write_dsp((size-1) >> 8);
342       sb_write_dsp(0x90);
343    }
344    else {                                    /* 16 bit */
345       size /= 2;
346       sb_write_dsp(0xB6);
347       sb_write_dsp(0x20);
348       sb_write_dsp((size-1) & 0xFF);
349       sb_write_dsp((size-1) >> 8);
350    }
351 }
352
353 static END_OF_FUNCTION(sb_play_buffer);
354
355
356
357 /* sb_interrupt:
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.
361  */
362 static int sb_interrupt()
363 {
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);
367    }
368    else {                                    /* poll dma position */
369       sb_dma_count++;
370       if (sb_dma_count > 16) {
371          sb_bufnum = (_dma_todo(_sb_dma) > (unsigned)sb_dma_size) ? 1 : 0;
372          sb_dma_count = 0;
373       }
374    }
375
376    if (!sb_semaphore) {
377       sb_semaphore = TRUE;
378
379       ENABLE();                              /* mix some more samples */
380       _mix_some_samples(sb_buf[sb_bufnum], _dos_ds, FALSE);
381       DISABLE();
382
383       sb_semaphore = FALSE;
384    } 
385
386    sb_bufnum = 1 - sb_bufnum; 
387
388    if (sb_16bit)                             /* acknowlege SB */
389       inportb(_sb_port+0x0F);
390    else
391       inportb(_sb_port+0x0E);
392
393    outportb(0x20, 0x20);                     /* acknowledge interrupt */
394    outportb(0xA0, 0x20);
395
396    return 0;
397 }
398
399 static END_OF_FUNCTION(sb_interrupt);
400
401
402
403 /* sb_detect:
404  *  SB detection routine. Uses the BLASTER environment variable,
405  *  or 'sensible' guesses if that doesn't exist.
406  */
407 static int sb_detect()
408 {
409    char *blaster = getenv("BLASTER");
410    char *msg;
411    int dma8 = 1;
412    int dma16 = 5;
413    int max_freq;
414    int default_freq;
415
416    /* what breed of SB are we looking for? */
417    switch (digi_card) {
418
419       case DIGI_SB10:
420          sb_dsp_ver = 0x100;
421          break;
422
423       case DIGI_SB15:
424          sb_dsp_ver = 0x200;
425          break;
426
427       case DIGI_SB20:
428          sb_dsp_ver = 0x201;
429          break;
430
431       case DIGI_SBPRO:
432          sb_dsp_ver = 0x300;
433          break;
434
435       case DIGI_SB16:
436          sb_dsp_ver = 0x400;
437          break;
438
439       default:
440          sb_dsp_ver = -1;
441          break;
442    } 
443
444    /* parse BLASTER env */
445    if (blaster) { 
446       while (*blaster) {
447          while ((*blaster == ' ') || (*blaster == '\t'))
448             blaster++;
449
450          if (*blaster) {
451             switch (*blaster) {
452                case 'a': case 'A':
453                   if (_sb_port < 0)
454                      _sb_port = strtol(blaster+1, NULL, 16);
455                   break;
456
457                case 'i': case 'I':
458                   if (_sb_irq < 0)
459                      _sb_irq = strtol(blaster+1, NULL, 10);
460                   //added on 11/5/98 by Victor Rachels to hardwire irq 2->9
461                       if (_sb_irq == 0x02)
462                        _sb_irq=0x09;
463                   //end this section addition
464                   break;
465
466                case 'd': case 'D':
467                   dma8 = strtol(blaster+1, NULL, 10);
468                   break;
469
470                case 'h': case 'H':
471                   dma16 = strtol(blaster+1, NULL, 10);
472                   break;
473             }
474
475             while ((*blaster) && (*blaster != ' ') && (*blaster != '\t'))
476                blaster++;
477          }
478       }
479    }
480
481    if (_sb_port < 0)
482       _sb_port = 0x220;
483
484    if (_sb_irq < 0)
485       _sb_irq = 7;
486
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 };
490       int i;
491
492       for (i=0; bases[i]; i++) {
493          _sb_port = bases[i];
494          if (sb_reset_dsp() == 0)
495             break;
496       }
497    }
498
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");
503       return FALSE;
504    }
505
506    if (sb_dsp_ver < 0)
507       sb_dsp_ver = sb_hw_dsp_ver;
508    else {
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");
512          return FALSE;
513       }
514    }
515
516    /* figure out the hardware interrupt number */
517    if (_sb_irq > 7)
518       sb_int = _sb_irq + 104;
519    else
520       sb_int = _sb_irq + 8;
521
522    /* what breed of SB? */
523    if (sb_dsp_ver >= 0x400) {
524       msg = "SB 16";
525       max_freq = 45454;
526       default_freq = 22727;
527    }
528    else if (sb_dsp_ver >= 0x300) {
529       msg = "SB Pro";
530       max_freq = 22727;
531       default_freq = 22727;
532    }
533    else if (sb_dsp_ver >= 0x201) {
534       msg = "SB 2.0";
535       max_freq = 45454;
536       default_freq = 22727;
537    }
538    else if (sb_dsp_ver >= 0x200) {
539       msg = "SB 1.5";
540       max_freq = 16129;
541       default_freq = 16129;
542    }
543    else {
544       msg = "SB 1.0";
545       max_freq = 16129;
546       default_freq = 16129;
547    }
548
549    /* set up the playback frequency */
550    if (_sb_freq <= 0)
551       _sb_freq = default_freq;
552
553    if (_sb_freq < 15000) {
554       _sb_freq = 11906;
555       sb_dma_size = 128;
556    }
557    else if (MIN(_sb_freq, max_freq) < 20000) {
558       _sb_freq = 16129;
559       sb_dma_size = 128;
560    }
561    else if (MIN(_sb_freq, max_freq) < 40000) {
562       _sb_freq = 22727;
563       sb_dma_size = 256;
564    }
565    else {
566       _sb_freq = 45454;
567       sb_dma_size = 512;
568    }
569
570    if (sb_dsp_ver <= 0x200)
571       sb_dma_size *= 4;
572
573    sb_dma_mix_size = sb_dma_size;
574
575    /* can we handle 16 bit playback? */
576    if (sb_dsp_ver >= 0x400) { 
577       if (_sb_dma < 0)
578          _sb_dma = dma16;
579       sb_16bit = TRUE;
580       sb_dma_size <<= 1;
581    }
582    else { 
583       if (_sb_dma < 0)
584          _sb_dma = dma8;
585       sb_16bit = FALSE;
586    }
587
588    /* can we handle stereo? */
589    if (sb_dsp_ver >= 0x300) {
590       sb_stereo = TRUE;
591       sb_dma_size <<= 1;
592       sb_dma_mix_size <<= 1;
593    }
594    else
595       sb_stereo = FALSE;
596
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);
600
601    return TRUE;
602 }
603
604
605
606 /* sb_init:
607  *  SB init routine: returns zero on success, -1 on failure.
608  */
609 static int sb_init(int voices)
610 {
611    if (sb_in_use) {
612       strcpy(allegro_error, "Can't use SB MIDI interface and DSP at the same time");
613       return -1;
614    }
615
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;
625       else
626          digi_card = DIGI_SB16;
627    }
628
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))
632          return -1;
633    }
634    else {                           /* auto-init dma, one big buffer */
635       if (_dma_allocate_mem(sb_dma_size*2, &sb_sel[0], &sb_buf[0]) != 0)
636          return -1;
637
638       sb_sel[1] = sb_sel[0];
639       sb_buf[1] = sb_buf[0] + sb_dma_size;
640    }
641
642    sb_lock_mem();
643
644    digi_sb.voices = voices;
645
646    if (_mixer_init(sb_dma_mix_size, _sb_freq, sb_stereo, sb_16bit, &digi_sb.voices) != 0)
647       return -1;
648
649    _mix_some_samples(sb_buf[0], _dos_ds, FALSE);
650    _mix_some_samples(sb_buf[1], _dos_ds, FALSE);
651    sb_bufnum = 0;
652
653    sb_default_pic1 = inportb(0x21);
654    sb_default_pic2 = inportb(0xA1);
655
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))));
659    }
660    else                             /* enable PIC-1 irq */
661       outportb(0x21, sb_default_pic1 & (~(1<<_sb_irq)));
662
663    _install_irq(sb_int, sb_interrupt);
664
665    sb_voice(1);
666    sb_set_sample_rate(_sb_freq);
667
668    if ((sb_hw_dsp_ver >= 0x300) && (sb_dsp_ver < 0x400))
669       sb_stereo_mode(sb_stereo);
670
671    if (sb_dsp_ver <= 0x200)
672       _dma_start(_sb_dma, sb_buf[0], sb_dma_size, FALSE);
673    else
674       _dma_start(_sb_dma, sb_buf[0], sb_dma_size*2, TRUE);
675
676    sb_play_buffer(sb_dma_size);
677
678    sb_in_use = TRUE;
679    return 0;
680 }
681
682
683
684 /* sb_exit:
685  *  SB driver cleanup routine, removes ints, stops dma, frees buffers, etc.
686  */
687 static void sb_exit()
688 {
689    /* halt sound output */
690    sb_voice(0);
691
692    /* stop dma transfer */
693    _dma_stop(_sb_dma);
694
695    if (sb_dsp_ver <= 0x0200)
696       sb_write_dsp(0xD0); 
697
698    sb_reset_dsp();
699
700    /* restore interrupts */
701    _remove_irq(sb_int);
702
703    /* reset PIC channels */
704    outportb(0x21, sb_default_pic1);
705    outportb(0xA1, sb_default_pic2);
706
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]);
711
712    _mixer_exit();
713
714    sb_hw_dsp_ver = sb_dsp_ver = -1;
715    sb_in_use = FALSE;
716 }
717
718
719
720 /* sb_midi_init:
721  *  Initialises the SB midi interface, returning zero on success.
722  */
723 static int sb_midi_init(int voices)
724 {
725    if (sb_in_use) {
726       strcpy(allegro_error, "Can't use SB MIDI interface and DSP at the same time");
727       return -1;
728    }
729
730    sb_dsp_ver = -1;
731
732    sb_lock_mem();
733
734    sprintf(sb_midi_desc, "Sound Blaster MIDI interface on port %X", _sb_port);
735
736    sb_in_use = TRUE;
737    return 0;
738 }
739
740
741
742 /* sb_midi_exit:
743  *  Resets the SB midi interface when we are finished.
744  */
745 static void sb_midi_exit()
746 {
747    sb_reset_dsp();
748    sb_in_use = FALSE;
749 }
750
751
752
753 /* sb_midi_output:
754  *  Writes a byte to the SB midi interface.
755  */
756 static void sb_midi_output(unsigned char data)
757 {
758    sb_write_dsp(0x38);
759    sb_write_dsp(data);
760 }
761
762 static END_OF_FUNCTION(sb_midi_output);
763
764
765
766 /* sb_lock_mem:
767  *  Locks all the memory touched by parts of the SB code that are executed
768  *  in an interrupt context.
769  */
770 static void sb_lock_mem()
771 {
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);
794 }
795