SHARE
TWEET

Allegro 4.2.2 Sound Blaster 8-bit volume patch by Ron Novy

a guest Apr 22nd, 2019 100 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*         ______   ___    ___
  2.  *        /\  _  \ /\_ \  /\_ \
  3.  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
  4.  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
  5.  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
  6.  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
  7.  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
  8.  *                                           /\____/
  9.  *                                           \_/__/
  10.  *
  11.  *      Soundblaster driver. Supports DMA driven sample playback (mixing
  12.  *      up to eight samples at a time) and raw note output to the SB MIDI
  13.  *      port. The Adlib (FM synth) MIDI playing code is in adlib.c.
  14.  *
  15.  *      By Shawn Hargreaves.
  16.  *
  17.  *      Input routines added by Ove Kaaven.
  18.  *
  19.  *      See readme.txt for copyright information.
  20.  */
  21.  
  22.  
  23. #include <string.h>
  24.  
  25. #include "allegro.h"
  26. #include "allegro/internal/aintern.h"
  27. #include "allegro/platform/aintdos.h"
  28.  
  29. #ifndef ALLEGRO_DOS
  30.    #error something is wrong with the makefile
  31. #endif
  32.  
  33.  
  34.  
  35. /* external interface to the digital SB driver */
  36. static int sb_detect(int input);
  37. static int sb_init(int input, int voices);
  38. static void sb_exit(int input);
  39. static int sb_set_mixer_volume(int volume);
  40. static int sb_buffer_size(void);
  41. static int sb_rec_cap_rate(int bits, int stereo);
  42. static int sb_rec_cap_parm(int rate, int bits, int stereo);
  43. static int sb_rec_source(int source);
  44. static int sb_rec_start(int rate, int bits, int stereo);
  45. static void sb_rec_stop(void);
  46. static int sb_rec_read(void *buf);
  47.  
  48. static char sb_desc[256] = EMPTY_STRING;
  49.  
  50.  
  51.  
  52. #define SB_DRIVER_CONTENTS             \
  53.    0, 0,                               \
  54.    MIXER_MAX_SFX, MIXER_DEF_SFX,       \
  55.    sb_detect,                          \
  56.    sb_init,                            \
  57.    sb_exit,                            \
  58.    sb_set_mixer_volume,                \
  59.    NULL,                               \
  60.    NULL,                               \
  61.    NULL,                               \
  62.    sb_buffer_size,                     \
  63.    _mixer_init_voice,                  \
  64.    _mixer_release_voice,               \
  65.    _mixer_start_voice,                 \
  66.    _mixer_stop_voice,                  \
  67.    _mixer_loop_voice,                  \
  68.    _mixer_get_position,                \
  69.    _mixer_set_position,                \
  70.    _mixer_get_volume,                  \
  71.    _mixer_set_volume,                  \
  72.    _mixer_ramp_volume,                 \
  73.    _mixer_stop_volume_ramp,            \
  74.    _mixer_get_frequency,               \
  75.    _mixer_set_frequency,               \
  76.    _mixer_sweep_frequency,             \
  77.    _mixer_stop_frequency_sweep,        \
  78.    _mixer_get_pan,                     \
  79.    _mixer_set_pan,                     \
  80.    _mixer_sweep_pan,                   \
  81.    _mixer_stop_pan_sweep,              \
  82.    _mixer_set_echo,                    \
  83.    _mixer_set_tremolo,                 \
  84.    _mixer_set_vibrato,                 \
  85.    0, 0,                               \
  86.    sb_rec_cap_rate,                    \
  87.    sb_rec_cap_parm,                    \
  88.    sb_rec_source,                      \
  89.    sb_rec_start,                       \
  90.    sb_rec_stop,                        \
  91.    sb_rec_read
  92.  
  93.  
  94.  
  95. DIGI_DRIVER digi_sb10 =
  96. {
  97.    DIGI_SB10,
  98.    empty_string,
  99.    empty_string,
  100.    "Sound Blaster 1.0",
  101.    SB_DRIVER_CONTENTS
  102. };
  103.  
  104.  
  105.  
  106. DIGI_DRIVER digi_sb15 =
  107. {
  108.    DIGI_SB15,
  109.    empty_string,
  110.    empty_string,
  111.    "Sound Blaster 1.5",
  112.    SB_DRIVER_CONTENTS
  113. };
  114.  
  115.  
  116.  
  117. DIGI_DRIVER digi_sb20 =
  118. {
  119.    DIGI_SB20,
  120.    empty_string,
  121.    empty_string,
  122.    "Sound Blaster 2.0",
  123.    SB_DRIVER_CONTENTS
  124. };
  125.  
  126.  
  127.  
  128. DIGI_DRIVER digi_sbpro =
  129. {
  130.    DIGI_SBPRO,
  131.    empty_string,
  132.    empty_string,
  133.    "Sound Blaster Pro",
  134.    SB_DRIVER_CONTENTS
  135. };
  136.  
  137.  
  138.  
  139. DIGI_DRIVER digi_sb16=
  140. {
  141.    DIGI_SB16,
  142.    empty_string,
  143.    empty_string,
  144.    "Sound Blaster 16",
  145.    SB_DRIVER_CONTENTS
  146. };
  147.  
  148.  
  149.  
  150. /* external interface to the SB midi output driver */
  151. static int sb_midi_detect(int input);
  152. static int sb_midi_init(int input, int voices);
  153. static void sb_midi_exit(int input);
  154. static void sb_midi_output(int data);
  155.  
  156. static char sb_midi_desc[256] = EMPTY_STRING;
  157.  
  158.  
  159.  
  160. MIDI_DRIVER midi_sb_out =
  161. {
  162.    MIDI_SB_OUT,
  163.    empty_string,
  164.    empty_string,
  165.    "SB MIDI interface",
  166.    0, 0, 0xFFFF, 0, -1, -1,
  167.    sb_midi_detect,
  168.    sb_midi_init,
  169.    sb_midi_exit,
  170.    NULL,
  171.    NULL,
  172.    sb_midi_output,
  173.    _dummy_load_patches,
  174.    _dummy_adjust_patches,
  175.    _dummy_key_on,
  176.    _dummy_noop1,
  177.    _dummy_noop2,
  178.    _dummy_noop3,
  179.    _dummy_noop2,
  180.    _dummy_noop2
  181. };
  182.  
  183.  
  184.  
  185. static int sb_in_use = FALSE;             /* is SB being used? */
  186. static int sb_stereo = FALSE;             /* in stereo mode? */
  187. static int sb_recording = FALSE;          /* in input mode? */
  188. static int sb_16bit = FALSE;              /* in 16 bit mode? */
  189. static int sb_midi_out_mode = FALSE;      /* active for MIDI output? */
  190. static int sb_midi_in_mode = FALSE;       /* active for MIDI input? */
  191. static int sb_int = -1;                   /* interrupt vector */
  192. static int sb_dsp_ver = -1;               /* SB DSP version */
  193. static int sb_dma8 = -1;                  /* 8-bit DMA channel (SB16) */
  194. static int sb_dma16 = -1;                 /* 16-bit DMA channel (SB16) */
  195. static int sb_hw_dsp_ver = -1;            /* as reported by autodetect */
  196. static int sb_dma_size = -1;              /* size of dma transfer in bytes */
  197. static int sb_dma_mix_size = -1;          /* number of samples to mix */
  198. static int sb_dma_count = 0;              /* need to resync with dma? */
  199. static volatile int sb_semaphore = FALSE; /* reentrant interrupt? */
  200.  
  201. static int sb_sel[2];                     /* selectors for the buffers */
  202. static unsigned long sb_buf[2];           /* pointers to the two buffers */
  203. static int sb_bufnum = 0;                 /* the one currently in use */
  204.  
  205. static int sb_recbufnum = 0;              /* the one to be returned */
  206.  
  207. static int sb_master_vol = -1;            /* stored mixer settings */
  208. static int sb_digi_vol = -1;
  209. static int sb_fm_vol = -1;
  210.  
  211. static int sb_detecting_midi = FALSE;
  212.  
  213. static void sb_lock_mem(void);
  214.  
  215.  
  216.  
  217. /* sb_read_dsp:
  218.  *  Reads a byte from the SB DSP chip. Returns -1 if it times out.
  219.  */
  220. static INLINE RET_VOLATILE int sb_read_dsp(void)
  221. {
  222.    int x;
  223.  
  224.    for (x=0; x<0xFFFF; x++)
  225.       if (inportb(0x0E + _sound_port) & 0x80)
  226.      return inportb(0x0A+_sound_port);
  227.  
  228.    return -1;
  229. }
  230.  
  231.  
  232.  
  233. /* sb_write_dsp:
  234.  *  Writes a byte to the SB DSP chip. Returns -1 if it times out.
  235.  */
  236. static INLINE RET_VOLATILE int sb_write_dsp(unsigned char byte)
  237. {
  238.    int x;
  239.  
  240.    for (x=0; x<0xFFFF; x++) {
  241.       if (!(inportb(0x0C+_sound_port) & 0x80)) {
  242.      outportb(0x0C+_sound_port, byte);
  243.      return 0;
  244.       }
  245.    }
  246.    return -1;
  247. }
  248.  
  249.  
  250.  
  251. /* _sb_voice:
  252.  *  Turns the SB speaker on or off.
  253.  */
  254. void _sb_voice(int state)
  255. {
  256.    if (state) {
  257.       sb_write_dsp(0xD1);
  258.  
  259.       if (sb_hw_dsp_ver >= 0x300) {          /* set up the mixer */
  260.  
  261.      if (sb_master_vol < 0) {
  262.         outportb(_sound_port+4, 0x22);   /* store master volume */
  263.         sb_master_vol = inportb(_sound_port+5);
  264.      }
  265.  
  266.      if (sb_digi_vol < 0) {
  267.         outportb(_sound_port+4, 4);      /* store DAC level */
  268.         sb_digi_vol = inportb(_sound_port+5);
  269.      }
  270.  
  271.      if (sb_fm_vol < 0) {
  272.         outportb(_sound_port+4, 0x26);   /* store FM level */
  273.         sb_fm_vol = inportb(_sound_port+5);
  274.      }
  275.       }
  276.    }
  277.    else {
  278.       sb_write_dsp(0xD3);
  279.  
  280.       if (sb_hw_dsp_ver >= 0x300) {          /* reset previous mixer settings */
  281.  
  282.      outportb(_sound_port+4, 0x22);      /* restore master volume */
  283.      outportb(_sound_port+5, sb_master_vol);
  284.  
  285.      outportb(_sound_port+4, 4);         /* restore DAC level */
  286.      outportb(_sound_port+5, sb_digi_vol);
  287.  
  288.      outportb(_sound_port+4, 0x26);      /* restore FM level */
  289.      outportb(_sound_port+5, sb_fm_vol);
  290.       }
  291.    }
  292. }
  293.  
  294.  
  295.  
  296. /* _sb_set_mixer:
  297.  *  Alters the SB-Pro hardware mixer.
  298.  */
  299. int _sb_set_mixer(int digi_volume, int midi_volume)
  300. {
  301.    if (sb_hw_dsp_ver < 0x300)
  302.       return -1;
  303.  
  304.    if (digi_volume >= 0) {                   /* set DAC level */
  305.       outportb(_sound_port+4, 4);
  306.       outportb(_sound_port+5, (digi_volume & 0xF0) | (digi_volume >> 4));
  307.    }
  308.  
  309.    if (midi_volume >= 0) {                   /* set FM level */
  310.       outportb(_sound_port+4, 0x26);
  311.       outportb(_sound_port+5, (midi_volume & 0xF0) | (midi_volume >> 4));
  312.    }
  313.  
  314.    return 0;
  315. }
  316.  
  317.  
  318.  
  319. /* sb_set_mixer_volume:
  320.  *  Sets the SB mixer volume for playing digital samples.
  321.  */
  322. static int sb_set_mixer_volume(int volume)
  323. {
  324.    return _sb_set_mixer(volume, -1);
  325. }
  326.  
  327.  
  328.  
  329. /* sb_stereo_mode:
  330.  *  Enables or disables stereo output for SB-Pro.
  331.  */
  332. static void sb_stereo_mode(int enable)
  333. {
  334.    outportb(_sound_port+0x04, 0x0E);
  335.    outportb(_sound_port+0x05, (enable ? 2 : 0));
  336. }
  337.  
  338.  
  339.  
  340. /* sb_input_stereo_mode:
  341.  *  Enables or disables stereo input for SB-Pro.
  342.  */
  343. static void sb_input_stereo_mode(int enable)
  344. {
  345.    sb_write_dsp(enable ? 0xA8 : 0xA0);
  346. }
  347.  
  348.  
  349.  
  350. /* sb_set_sample_rate:
  351.  *  The parameter is the rate to set in Hz (samples per second).
  352.  */
  353. static void sb_set_sample_rate(unsigned int rate)
  354. {
  355.    if (sb_16bit) {
  356.       sb_write_dsp(0x41);
  357.       sb_write_dsp(rate >> 8);
  358.       sb_write_dsp(rate & 0xff);
  359.    }
  360.    else {
  361.       if (sb_stereo)
  362.      rate *= 2;
  363.  
  364.       sb_write_dsp(0x40);
  365.       sb_write_dsp((unsigned char)(256-1000000/rate));
  366.    }
  367. }
  368.  
  369.  
  370.  
  371. /* sb_set_input_sample_rate:
  372.  *  The parameter is the rate to set in Hz (samples per second).
  373.  */
  374. static void sb_set_input_sample_rate(unsigned int rate, int stereo)
  375. {
  376.    if (sb_16bit) {
  377.       sb_write_dsp(0x42);
  378.       sb_write_dsp(rate >> 8);
  379.       sb_write_dsp(rate & 0xff);
  380.    }
  381.    else {
  382.       if (stereo)
  383.      rate *= 2;
  384.  
  385.       sb_write_dsp(0x40);
  386.       sb_write_dsp((unsigned char)(256-1000000/rate));
  387.    }
  388. }
  389.  
  390.  
  391.  
  392. /* _sb_reset_dsp:
  393.  *  Resets the SB DSP chip, returning -1 on error.
  394.  */
  395. int _sb_reset_dsp(int data)
  396. {
  397.    int x;
  398.  
  399.    outportb(0x06+_sound_port, data);
  400.  
  401.    for (x=0; x<8; x++)
  402.       inportb(0x06+_sound_port);
  403.  
  404.    outportb(0x06+_sound_port, 0);
  405.  
  406.    if (sb_read_dsp() != 0xAA)
  407.       return -1;
  408.  
  409.    return 0;
  410. }
  411.  
  412.  
  413.  
  414. /* _sb_read_dsp_version:
  415.  *  Reads the version number of the SB DSP chip, returning -1 on error.
  416.  */
  417. int _sb_read_dsp_version(void)
  418. {
  419.    int x, y;
  420.  
  421.    if (sb_hw_dsp_ver > 0)
  422.       return sb_hw_dsp_ver;
  423.  
  424.    if (_sound_port <= 0)
  425.       _sound_port = 0x220;
  426.  
  427.    if (_sb_reset_dsp(1) != 0) {
  428.       sb_hw_dsp_ver = -1;
  429.    }
  430.    else {
  431.       sb_write_dsp(0xE1);
  432.       x = sb_read_dsp();
  433.       y = sb_read_dsp();
  434.       sb_hw_dsp_ver = ((x << 8) | y);
  435.    }
  436.  
  437.    return sb_hw_dsp_ver;
  438. }
  439.  
  440.  
  441.  
  442. /* sb_buffer_size:
  443.  *  Returns the current DMA buffer size, for use by the audiostream code.
  444.  */
  445. static int sb_buffer_size(void)
  446. {
  447.    return (sb_stereo ? sb_dma_mix_size/2 : sb_dma_mix_size);
  448. }
  449.  
  450.  
  451.  
  452. /* sb_play_buffer:
  453.  *  Starts a dma transfer of size bytes. On cards capable of it, the
  454.  *  transfer will use auto-initialised dma, so there is no need to call
  455.  *  this routine more than once. On older cards it must be called from
  456.  *  the end-of-buffer handler to switch to the new buffer.
  457.  */
  458. static void sb_play_buffer(int size)
  459. {
  460.    if (sb_dsp_ver <= 0x200) {                /* 8 bit single-shot */
  461.       sb_write_dsp(0x14);
  462.       sb_write_dsp((size-1) & 0xFF);
  463.       sb_write_dsp((size-1) >> 8);
  464.    }
  465.    else if (sb_dsp_ver < 0x400) {            /* 8 bit auto-initialised */
  466.       sb_write_dsp(0x48);
  467.       sb_write_dsp((size-1) & 0xFF);
  468.       sb_write_dsp((size-1) >> 8);
  469.       sb_write_dsp(0x90);
  470.    }
  471.    else {                                    /* 16 bit */
  472.       size /= 2;
  473.       sb_write_dsp(0xB6);
  474.       sb_write_dsp(0x30);
  475.       sb_write_dsp((size-1) & 0xFF);
  476.       sb_write_dsp((size-1) >> 8);
  477.    }
  478. }
  479.  
  480. END_OF_STATIC_FUNCTION(sb_play_buffer);
  481.  
  482.  
  483.  
  484. /* sb_record_buffer:
  485.  *  Starts a dma transfer of size bytes. On cards capable of it, the
  486.  *  transfer will use auto-initialised dma, so there is no need to call
  487.  *  this routine more than once. On older cards it must be called from
  488.  *  the end-of-buffer handler to switch to the new buffer.
  489.  */
  490. static void sb_record_buffer(int size, int stereo, int bits)
  491. {
  492.    if (sb_dsp_ver <= 0x200) {                /* 8 bit single-shot */
  493.       sb_write_dsp(0x24);
  494.       sb_write_dsp((size-1) & 0xFF);
  495.       sb_write_dsp((size-1) >> 8);
  496.    }
  497.    else if (sb_dsp_ver < 0x400) {            /* 8 bit auto-initialised */
  498.       sb_write_dsp(0x48);
  499.       sb_write_dsp((size-1) & 0xFF);
  500.       sb_write_dsp((size-1) >> 8);
  501.       sb_write_dsp(0x98);
  502.    }
  503.    else if (bits <= 8) {                     /* 8 bit */
  504.       sb_write_dsp(0xCE);
  505.       sb_write_dsp((stereo) ? 0x20 : 0x00);
  506.       sb_write_dsp((size-1) & 0xFF);
  507.       sb_write_dsp((size-1) >> 8);
  508.    }
  509.    else {                                    /* 16 bit */
  510.       size /= 2;
  511.       sb_write_dsp(0xBE);
  512.       sb_write_dsp((stereo) ? 0x20 : 0x00);
  513.       sb_write_dsp((size-1) & 0xFF);
  514.       sb_write_dsp((size-1) >> 8);
  515.    }
  516. }
  517.  
  518. END_OF_STATIC_FUNCTION(sb_record_buffer);
  519.  
  520.  
  521.  
  522. /* sb_interrupt:
  523.  *  The SB end-of-buffer interrupt handler. Swaps to the other buffer
  524.  *  if the card doesn't have auto-initialised dma, and then refills the
  525.  *  buffer that just finished playing.
  526.  */
  527. static int sb_interrupt(void)
  528. {
  529.    unsigned char isr;
  530.  
  531.    if (sb_dsp_ver >= 0x400) {
  532.       /* read SB16 ISR mask */
  533.       outportb(_sound_port+4, 0x82);
  534.       isr = inportb(_sound_port+5) & 7;
  535.  
  536.       if (isr & 4) {
  537.      /* MPU-401 interrupt */
  538.      _mpu_poll();
  539.      _eoi(_sound_irq);
  540.      return 0;
  541.       }
  542.  
  543.       if (!(isr & 3)) {
  544.      /* unknown interrupt */
  545.      _eoi(_sound_irq);
  546.      return 0;
  547.       }
  548.    }
  549.  
  550.    if (sb_dsp_ver <= 0x200) {                /* not auto-initialised */
  551.       _dma_start(_sound_dma, sb_buf[1-sb_bufnum], sb_dma_size, FALSE, FALSE);
  552.       if (sb_recording)
  553.      sb_record_buffer(sb_dma_size, FALSE, 8);
  554.       else
  555.      sb_play_buffer(sb_dma_size);
  556.    }
  557.    else {                                    /* poll dma position */
  558.       sb_dma_count++;
  559.       if (sb_dma_count > 16) {
  560.      sb_bufnum = (_dma_todo(_sound_dma) > (unsigned)sb_dma_size) ? 1 : 0;
  561.      sb_dma_count = 0;
  562.       }
  563.    }
  564.  
  565.    if ((!sb_semaphore) && (!sb_recording)) {
  566.       sb_semaphore = TRUE;
  567.  
  568.       ENABLE();                              /* mix some more samples */
  569.       _mix_some_samples(sb_buf[sb_bufnum], _dos_ds, sb_16bit);
  570.       DISABLE();
  571.  
  572.       sb_semaphore = FALSE;
  573.    }
  574.  
  575.    sb_bufnum = 1 - sb_bufnum;
  576.  
  577.    if ((sb_recording) && (digi_recorder)) {
  578.       sb_semaphore = TRUE;
  579.  
  580.       ENABLE();                              /* sample input callback */
  581.       digi_recorder();
  582.       DISABLE();
  583.  
  584.       sb_semaphore = FALSE;
  585.    }
  586.  
  587.    if (sb_16bit)                             /* acknowledge SB */
  588.       inportb(_sound_port+0x0F);
  589.    else
  590.       inportb(_sound_port+0x0E);
  591.  
  592.    _eoi(_sound_irq);                         /* acknowledge interrupt */
  593.    return 0;
  594. }
  595.  
  596. END_OF_STATIC_FUNCTION(sb_interrupt);
  597.  
  598.  
  599.  
  600. /* sb_start:
  601.  *  Starts up the sound output.
  602.  */
  603. static void sb_start(void)
  604. {
  605.    sb_bufnum = 0;
  606.  
  607.    _sb_voice(1);
  608.    sb_set_sample_rate(_sound_freq);
  609.  
  610.    if ((sb_hw_dsp_ver >= 0x300) && (sb_dsp_ver < 0x400))
  611.       sb_stereo_mode(sb_stereo);
  612.  
  613.    if (sb_dsp_ver <= 0x200)
  614.       _dma_start(_sound_dma, sb_buf[0], sb_dma_size, FALSE, FALSE);
  615.    else
  616.       _dma_start(_sound_dma, sb_buf[0], sb_dma_size*2, TRUE, FALSE);
  617.  
  618.    sb_play_buffer(sb_dma_size);
  619. }
  620.  
  621.  
  622.  
  623. /* sb_stop:
  624.  *  Stops the sound output.
  625.  */
  626. static void sb_stop(void)
  627. {
  628.    /* halt sound output */
  629.    _sb_voice(0);
  630.  
  631.    /* stop dma transfer */
  632.    _dma_stop(_sound_dma);
  633.  
  634.    if (sb_dsp_ver <= 0x0200)
  635.       sb_write_dsp(0xD0);
  636.  
  637.    _sb_reset_dsp(1);
  638. }
  639.  
  640.  
  641.  
  642. /* sb_detect:
  643.  *  SB detection routine. Uses the BLASTER environment variable,
  644.  *  or 'sensible' guesses if that doesn't exist.
  645.  */
  646. static int sb_detect(int input)
  647. {
  648.    char *blaster = getenv("BLASTER");
  649.    char tmp[64], *msg;
  650.    int cmask;
  651.    int max_freq;
  652.    int default_freq;
  653.  
  654.    if (!sb_detecting_midi) {
  655.       /* input mode only works on the top of an existing output driver */
  656.       if (input) {
  657.      if (digi_driver != digi_input_driver) {
  658.         ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("SB output driver must be installed before input can be read"));
  659.         return FALSE;
  660.      }
  661.      return TRUE;
  662.       }
  663.  
  664.       /* what breed of SB are we looking for? */
  665.       switch (digi_card) {
  666.  
  667.      case DIGI_SB10:
  668.         sb_dsp_ver = 0x100;
  669.         break;
  670.  
  671.      case DIGI_SB15:
  672.         sb_dsp_ver = 0x200;
  673.         break;
  674.  
  675.      case DIGI_SB20:
  676.         sb_dsp_ver = 0x201;
  677.         break;
  678.  
  679.      case DIGI_SBPRO:
  680.         sb_dsp_ver = 0x300;
  681.         break;
  682.  
  683.      case DIGI_SB16:
  684.         sb_dsp_ver = 0x400;
  685.         break;
  686.  
  687.      default:
  688.         sb_dsp_ver = -1;
  689.         break;
  690.       }
  691.    }
  692.    else
  693.       sb_dsp_ver = -1;
  694.  
  695.    /* parse BLASTER env */
  696.    if (blaster) {
  697.       while (*blaster) {
  698.      while ((*blaster == ' ') || (*blaster == '\t'))
  699.         blaster++;
  700.  
  701.      if (*blaster) {
  702.         switch (*blaster) {
  703.  
  704.            case 'a': case 'A':
  705.           if (_sound_port < 0)
  706.              _sound_port = strtol(blaster+1, NULL, 16);
  707.           break;
  708.  
  709.            case 'i': case 'I':
  710.           if (_sound_irq < 0)
  711.              _sound_irq = strtol(blaster+1, NULL, 10);
  712.           break;
  713.  
  714.            case 'd': case 'D':
  715.           sb_dma8 = strtol(blaster+1, NULL, 10);
  716.           break;
  717.  
  718.            case 'h': case 'H':
  719.           sb_dma16 = strtol(blaster+1, NULL, 10);
  720.           break;
  721.         }
  722.  
  723.         while ((*blaster) && (*blaster != ' ') && (*blaster != '\t'))
  724.            blaster++;
  725.      }
  726.       }
  727.    }
  728.  
  729.    if (_sound_port < 0)
  730.       _sound_port = 0x220;
  731.  
  732.    /* make sure we got a good port address */
  733.    if (_sb_reset_dsp(1) != 0) {
  734.       static int bases[] = { 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0 };
  735.       int i;
  736.  
  737.       for (i=0; bases[i]; i++) {
  738.      _sound_port = bases[i];
  739.      if (_sb_reset_dsp(1) == 0)
  740.         break;
  741.       }
  742.    }
  743.  
  744.    /* check if the card really exists */
  745.    _sb_read_dsp_version();
  746.    if (sb_hw_dsp_ver < 0) {
  747.       ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Sound Blaster not found"));
  748.       return FALSE;
  749.    }
  750.  
  751.    if (sb_dsp_ver < 0) {
  752.       sb_dsp_ver = sb_hw_dsp_ver;
  753.    }
  754.    else {
  755.       if (sb_dsp_ver > sb_hw_dsp_ver) {
  756.      sb_hw_dsp_ver = sb_dsp_ver = -1;
  757.      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Older SB version detected"));
  758.      return FALSE;
  759.       }
  760.    }
  761.  
  762.    if (sb_dsp_ver >= 0x400) {
  763.       /* read configuration from SB16 card */
  764.       if (_sound_irq < 0) {
  765.      outportb(_sound_port+4, 0x80);
  766.      cmask = inportb(_sound_port+5);
  767.      if (cmask&1) _sound_irq = 2; /* or 9? */
  768.      if (cmask&2) _sound_irq = 5;
  769.      if (cmask&4) _sound_irq = 7;
  770.      if (cmask&8) _sound_irq = 10;
  771.       }
  772.       if ((sb_dma8 < 0) || (sb_dma16 < 0)) {
  773.      outportb(_sound_port+4, 0x81);
  774.      cmask = inportb(_sound_port+5);
  775.      if (sb_dma8 < 0) {
  776.         if (cmask&1) sb_dma8 = 0;
  777.         if (cmask&2) sb_dma8 = 1;
  778.         if (cmask&8) sb_dma8 = 3;
  779.      }
  780.      if (sb_dma16 < 0) {
  781.         sb_dma16 = sb_dma8;
  782.         if (cmask&0x20) sb_dma16 = 5;
  783.         if (cmask&0x40) sb_dma16 = 6;
  784.         if (cmask&0x80) sb_dma16 = 7;
  785.      }
  786.       }
  787.    }
  788.  
  789.    /* if nothing else works */
  790.    if (_sound_irq < 0)
  791.       _sound_irq = 7;
  792.  
  793.    if (sb_dma8 < 0)
  794.       sb_dma8 = 1;
  795.  
  796.    if (sb_dma16 < 0)
  797.       sb_dma16 = 5;
  798.  
  799.    /* figure out the hardware interrupt number */
  800.    sb_int = _map_irq(_sound_irq);
  801.  
  802.    if (!sb_detecting_midi) {
  803.       /* what breed of SB? */
  804.       if (sb_dsp_ver >= 0x400) {
  805.      msg = "SB 16";
  806.      max_freq = 45454;
  807.      default_freq = 22727;
  808.       }
  809.       else if (sb_dsp_ver >= 0x300) {
  810.      msg = "SB Pro";
  811.      max_freq = 22727;
  812.      default_freq = 22727;
  813.       }
  814.       else if (sb_dsp_ver >= 0x201) {
  815.      msg = "SB 2.0";
  816.      max_freq = 45454;
  817.      default_freq = 22727;
  818.       }
  819.       else if (sb_dsp_ver >= 0x200) {
  820.      msg = "SB 1.5";
  821.      max_freq = 16129;
  822.      default_freq = 16129;
  823.       }
  824.       else {
  825.      msg = "SB 1.0";
  826.      max_freq = 16129;
  827.      default_freq = 16129;
  828.       }
  829.  
  830.       /* set up the playback frequency */
  831.       if (_sound_freq <= 0)
  832.      _sound_freq = default_freq;
  833.  
  834.       if (_sound_freq < 15000) {
  835.      _sound_freq = 11906;
  836.      sb_dma_size = 128;
  837.       }
  838.       else if (MIN(_sound_freq, max_freq) < 20000) {
  839.      _sound_freq = 16129;
  840.      sb_dma_size = 128;
  841.       }
  842.       else if (MIN(_sound_freq, max_freq) < 40000) {
  843.      _sound_freq = 22727;
  844.      sb_dma_size = 256;
  845.       }
  846.       else {
  847.      _sound_freq = 45454;
  848.      sb_dma_size = 512;
  849.       }
  850.  
  851.       if (sb_dsp_ver <= 0x200)
  852.      sb_dma_size *= 4;
  853.  
  854.       sb_dma_mix_size = sb_dma_size;
  855.  
  856.       /* can we handle 16 bit sound? */
  857.       if (sb_dsp_ver >= 0x400) {
  858.      if (_sound_dma < 0)
  859.         _sound_dma = sb_dma16;
  860.      else
  861.         sb_dma16 = _sound_dma;
  862.  
  863.      sb_16bit = TRUE;
  864.      digi_driver->rec_cap_bits = 24;
  865.      sb_dma_size <<= 1;
  866.       }
  867.       else {
  868.      if (_sound_dma < 0)
  869.         _sound_dma = sb_dma8;
  870.      else
  871.         sb_dma8 = _sound_dma;
  872.  
  873.      sb_16bit = FALSE;
  874.      digi_driver->rec_cap_bits = 8;
  875.       }
  876.  
  877.       /* can we handle stereo? */
  878.       if (sb_dsp_ver >= 0x300) {
  879.      sb_stereo = TRUE;
  880.      digi_driver->rec_cap_stereo = TRUE;
  881.      sb_dma_size <<= 1;
  882.      sb_dma_mix_size <<= 1;
  883.       }
  884.       else {
  885.      sb_stereo = FALSE;
  886.      digi_driver->rec_cap_stereo = FALSE;
  887.       }
  888.  
  889.       /* set up the card description */
  890.       uszprintf(sb_desc, sizeof(sb_desc), get_config_text("%s (%d hz) on port %X, using IRQ %d and DMA channel %d"),
  891.         uconvert_ascii(msg, tmp), _sound_freq, _sound_port, _sound_irq, _sound_dma);
  892.  
  893.       digi_driver->desc = sb_desc;
  894.    }
  895.  
  896.    return TRUE;
  897. }
  898.  
  899.  
  900.  
  901. /* sb_init:
  902.  *  SB init routine: returns zero on success, -1 on failure.
  903.  */
  904. static int sb_init(int input, int voices)
  905. {
  906.    if (input)
  907.       return 0;
  908.  
  909.    if (sb_in_use) {
  910.       ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can't use SB MIDI interface and DSP at the same time"));
  911.       return -1;
  912.    }
  913.  
  914.    if (sb_dsp_ver <= 0x200) {       /* two conventional mem buffers */
  915.       if ((_dma_allocate_mem(sb_dma_size, &sb_sel[0], &sb_buf[0]) != 0) ||
  916.       (_dma_allocate_mem(sb_dma_size, &sb_sel[1], &sb_buf[1]) != 0))
  917.      return -1;
  918.    }
  919.    else {                           /* auto-init dma, one big buffer */
  920.       if (_dma_allocate_mem(sb_dma_size*2, &sb_sel[0], &sb_buf[0]) != 0)
  921.      return -1;
  922.  
  923.       sb_sel[1] = sb_sel[0];
  924.       sb_buf[1] = sb_buf[0] + sb_dma_size;
  925.    }
  926.  
  927.    sb_lock_mem();
  928.  
  929.    digi_driver->voices = voices;
  930.  
  931.    if (_mixer_init(sb_dma_mix_size, _sound_freq, sb_stereo, sb_16bit, &digi_driver->voices) != 0)
  932.       return -1;
  933.  
  934.    _mix_some_samples(sb_buf[0], _dos_ds, sb_16bit);
  935.    _mix_some_samples(sb_buf[1], _dos_ds, sb_16bit);
  936.  
  937.    _enable_irq(_sound_irq);
  938.    _install_irq(sb_int, sb_interrupt);
  939.  
  940.    sb_start();
  941.  
  942.    sb_in_use = TRUE;
  943.    return 0;
  944. }
  945.  
  946.  
  947.  
  948. /* sb_exit:
  949.  *  SB driver cleanup routine, removes ints, stops dma, frees buffers, etc.
  950.  */
  951. static void sb_exit(int input)
  952. {
  953.    if (input)
  954.       return;
  955.  
  956.    sb_stop();
  957.    _remove_irq(sb_int);
  958.    _restore_irq(_sound_irq);
  959.  
  960.    __dpmi_free_dos_memory(sb_sel[0]);
  961.  
  962.    if (sb_sel[1] != sb_sel[0])
  963.       __dpmi_free_dos_memory(sb_sel[1]);
  964.  
  965.    _mixer_exit();
  966.  
  967.    sb_hw_dsp_ver = sb_dsp_ver = -1;
  968.    sb_in_use = FALSE;
  969. }
  970.  
  971.  
  972.  
  973. /* sb_rec_cap_rate:
  974.  *  Returns maximum input sampling rate.
  975.  */
  976. static int sb_rec_cap_rate(int bits, int stereo)
  977. {
  978.    if (sb_dsp_ver < 0)
  979.       return 0;
  980.  
  981.    if (sb_dsp_ver >= 0x400)
  982.       /* SB16 can handle 45kHz under all circumstances */
  983.       return 45454;
  984.  
  985.    /* lesser SB cards can't handle 16-bit */
  986.    if (bits != 8)
  987.       return 0;
  988.  
  989.    if (sb_dsp_ver >= 0x300)
  990.       /* SB Pro can handle 45kHz, but only half that in stereo */
  991.       return (stereo) ? 22727 : 45454;
  992.  
  993.    /* lesser SB cards can't handle stereo */
  994.    if (stereo)
  995.       return 0;
  996.  
  997.    if (sb_dsp_ver >= 0x201)
  998.       /* SB 2.0 supports 15kHz */
  999.       return 15151;
  1000.  
  1001.    /* SB 1.x supports 13kHz */
  1002.    return 13157;
  1003. }
  1004.  
  1005.  
  1006.  
  1007. /* sb_rec_cap_parm:
  1008.  *  Returns whether the specified parameters can be set.
  1009.  */
  1010. static int sb_rec_cap_parm(int rate, int bits, int stereo)
  1011. {
  1012.    int c, r;
  1013.  
  1014.    if ((r = sb_rec_cap_rate(bits, stereo)) <= 0)
  1015.       return 0;
  1016.  
  1017.    if (r < rate)
  1018.       return -r;
  1019.  
  1020.    if (sb_dsp_ver >= 0x400) {
  1021.       /* if bits==8 and rate==_sound_freq, bidirectional is possible,
  1022.      but that's not implemented yet */
  1023.       return 1;
  1024.    }
  1025.  
  1026.    if (stereo)
  1027.       rate *= 2;
  1028.  
  1029.    c = 1000000/rate;
  1030.    r = 1000000/c;
  1031.    if (r != rate)
  1032.       return -r;
  1033.  
  1034.    return 1;
  1035. }
  1036.  
  1037.  
  1038.  
  1039. /* sb_rec_source:
  1040.  *  Sets the sampling source for audio recording.
  1041.  */
  1042. static int sb_rec_source(int source)
  1043. {
  1044.    int v1, v2;
  1045.  
  1046.    if (sb_hw_dsp_ver >= 0x400) {
  1047.       /* SB16 */
  1048.       switch (source) {
  1049.  
  1050.      case SOUND_INPUT_MIC:
  1051.         v1 = 1;
  1052.         v2 = 1;
  1053.         break;
  1054.  
  1055.      case SOUND_INPUT_LINE:
  1056.         v1 = 16;
  1057.         v2 = 8;
  1058.         break;
  1059.  
  1060.      case SOUND_INPUT_CD:
  1061.         v1 = 4;
  1062.         v2 = 2;
  1063.         break;
  1064.  
  1065.      default:
  1066.         return -1;
  1067.       }
  1068.  
  1069.       outportb(_sound_port+4, 0x3D);
  1070.       outportb(_sound_port+5, v1);
  1071.  
  1072.       outportb(_sound_port+4, 0x3E);
  1073.       outportb(_sound_port+5, v2);
  1074.  
  1075.       return 0;
  1076.    }
  1077.    else if (sb_hw_dsp_ver >= 0x300) {
  1078.       /* SB Pro */
  1079.       outportb(_sound_port+4, 0xC);
  1080.       v1 = inportb(_sound_port+5);
  1081.  
  1082.       switch (source) {
  1083.  
  1084.      case SOUND_INPUT_MIC:
  1085.         v1 = (v1 & 0xF9);
  1086.         break;
  1087.  
  1088.      case SOUND_INPUT_LINE:
  1089.         v1 = (v1 & 0xF9) | 6;
  1090.         break;
  1091.  
  1092.      case SOUND_INPUT_CD:
  1093.         v1 = (v1 & 0xF9) | 2;
  1094.         break;
  1095.  
  1096.      default:
  1097.         return -1;
  1098.       }
  1099.  
  1100.       outportb(_sound_port+4, 0xC);
  1101.       outportb(_sound_port+5, v1);
  1102.  
  1103.       return 0;
  1104.    }
  1105.  
  1106.    return -1;
  1107. }
  1108.  
  1109.  
  1110.  
  1111. /* sb_rec_start:
  1112.  *  Stops playback, switches the SB to A/D mode, and starts recording.
  1113.  *  Returns the DMA buffer size if successful.
  1114.  */
  1115. static int sb_rec_start(int rate, int bits, int stereo)
  1116. {
  1117.    if (sb_rec_cap_parm(rate, bits, stereo) <= 0)
  1118.       return 0;
  1119.  
  1120.    sb_stop();
  1121.  
  1122.    sb_16bit = (bits>8);
  1123.    _sound_dma = (sb_16bit) ? sb_dma16 : sb_dma8;
  1124.    sb_recording = TRUE;
  1125.    sb_recbufnum = sb_bufnum = 0;
  1126.  
  1127.    _sb_voice(1);
  1128.    sb_set_input_sample_rate(rate, stereo);
  1129.  
  1130.    if ((sb_hw_dsp_ver >= 0x300) && (sb_dsp_ver < 0x400))
  1131.       sb_input_stereo_mode(stereo);
  1132.  
  1133.    if (sb_dsp_ver <= 0x200)
  1134.       _dma_start(_sound_dma, sb_buf[0], sb_dma_size, FALSE, TRUE);
  1135.    else
  1136.       _dma_start(_sound_dma, sb_buf[0], sb_dma_size*2, TRUE, TRUE);
  1137.  
  1138.    sb_record_buffer(sb_dma_size, stereo, bits);
  1139.  
  1140.    return sb_dma_size;
  1141. }
  1142.  
  1143.  
  1144.  
  1145. /* sb_rec_stop:
  1146.  *  Stops recording, switches the SB back to D/A mode, and restarts playback.
  1147.  */
  1148. static void sb_rec_stop(void)
  1149. {
  1150.    if (!sb_recording)
  1151.       return;
  1152.  
  1153.    sb_stop();
  1154.  
  1155.    sb_recording = FALSE;
  1156.    sb_16bit = (sb_dsp_ver >= 0x400);
  1157.    _sound_dma = (sb_16bit) ? sb_dma16 : sb_dma8;
  1158.  
  1159.    _mix_some_samples(sb_buf[0], _dos_ds, sb_16bit);
  1160.    _mix_some_samples(sb_buf[1], _dos_ds, sb_16bit);
  1161.  
  1162.    sb_start();
  1163. }
  1164.  
  1165.  
  1166.  
  1167. /* sb_rec_read:
  1168.  *  Retrieves the just recorded DMA buffer, if there is one.
  1169.  */
  1170. static int sb_rec_read(void *buf)
  1171. {
  1172.    if (!sb_recording)
  1173.       return 0;
  1174.  
  1175.    if (sb_bufnum == sb_recbufnum)
  1176.       return 0;
  1177.  
  1178.    dosmemget(sb_buf[sb_recbufnum], sb_dma_size, buf);
  1179.    sb_recbufnum = 1-sb_recbufnum;
  1180.  
  1181.    return 1;
  1182. }
  1183.  
  1184. END_OF_STATIC_FUNCTION(sb_rec_read);
  1185.  
  1186.  
  1187.  
  1188. /* sb_midi_interrupt:
  1189.  *  Interrupt handler for the SB MIDI input.
  1190.  */
  1191. static int sb_midi_interrupt(void)
  1192. {
  1193.    int c = sb_read_dsp();
  1194.  
  1195.    if ((c >= 0) && (midi_recorder))
  1196.       midi_recorder(c);
  1197.  
  1198.    _eoi(_sound_irq);
  1199.    return 0;
  1200. }
  1201.  
  1202. END_OF_STATIC_FUNCTION(sb_midi_interrupt);
  1203.  
  1204.  
  1205.  
  1206. /* sb_midi_output:
  1207.  *  Writes a byte to the SB midi interface.
  1208.  */
  1209. static void sb_midi_output(int data)
  1210. {
  1211.    sb_write_dsp(data);
  1212. }
  1213.  
  1214. END_OF_STATIC_FUNCTION(sb_midi_output);
  1215.  
  1216.  
  1217.  
  1218. /* sb_midi_detect:
  1219.  *  Detection routine for the SB MIDI interface.
  1220.  */
  1221. static int sb_midi_detect(int input)
  1222. {
  1223.    int ret;
  1224.  
  1225.    if ((input) && (sb_midi_out_mode))
  1226.       return TRUE;
  1227.  
  1228.    sb_detecting_midi = TRUE;
  1229.  
  1230.    ret = sb_detect(FALSE);
  1231.  
  1232.    sb_detecting_midi = FALSE;
  1233.  
  1234.    return ret;
  1235. }
  1236.  
  1237.  
  1238.  
  1239. /* sb_midi_init:
  1240.  *  Initialises the SB midi interface, returning zero on success.
  1241.  */
  1242. static int sb_midi_init(int input, int voices)
  1243. {
  1244.    if ((sb_in_use) && (!sb_midi_out_mode)) {
  1245.       ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can't use SB MIDI interface and DSP at the same time"));
  1246.       return -1;
  1247.    }
  1248.  
  1249.    sb_dsp_ver = -1;
  1250.    sb_lock_mem();
  1251.  
  1252.    uszprintf(sb_midi_desc, sizeof(sb_midi_desc), get_config_text("Sound Blaster MIDI interface on port %X"), _sound_port);
  1253.    midi_sb_out.desc = sb_midi_desc;
  1254.  
  1255.    if (input) {
  1256.       _enable_irq(_sound_irq);
  1257.       _install_irq(sb_int, sb_midi_interrupt);
  1258.       sb_midi_in_mode = TRUE;
  1259.    }
  1260.    else
  1261.       sb_midi_out_mode = TRUE;
  1262.  
  1263.    sb_write_dsp(0x35);
  1264.  
  1265.    sb_in_use = TRUE;
  1266.    return 0;
  1267. }
  1268.  
  1269.  
  1270.  
  1271. /* sb_midi_exit:
  1272.  *  Resets the SB midi interface when we are finished.
  1273.  */
  1274. static void sb_midi_exit(int input)
  1275. {
  1276.    if (input) {
  1277.       _remove_irq(sb_int);
  1278.       _restore_irq(_sound_irq);
  1279.       sb_midi_in_mode = FALSE;
  1280.    }
  1281.    else
  1282.       sb_midi_out_mode = FALSE;
  1283.  
  1284.    if ((!sb_midi_in_mode) && (!sb_midi_out_mode)) {
  1285.       _sb_reset_dsp(1);
  1286.       sb_in_use = FALSE;
  1287.    }
  1288. }
  1289.  
  1290.  
  1291.  
  1292. /* sb_lock_mem:
  1293.  *  Locks all the memory touched by parts of the SB code that are executed
  1294.  *  in an interrupt context.
  1295.  */
  1296. static void sb_lock_mem(void)
  1297. {
  1298.    extern void _mpu_poll_end(void);
  1299.  
  1300.    LOCK_VARIABLE(digi_sb10);
  1301.    LOCK_VARIABLE(digi_sb15);
  1302.    LOCK_VARIABLE(digi_sb20);
  1303.    LOCK_VARIABLE(digi_sbpro);
  1304.    LOCK_VARIABLE(digi_sb16);
  1305.    LOCK_VARIABLE(midi_sb_out);
  1306.    LOCK_VARIABLE(_sound_freq);
  1307.    LOCK_VARIABLE(_sound_port);
  1308.    LOCK_VARIABLE(_sound_dma);
  1309.    LOCK_VARIABLE(_sound_irq);
  1310.    LOCK_VARIABLE(sb_int);
  1311.    LOCK_VARIABLE(sb_in_use);
  1312.    LOCK_VARIABLE(sb_recording);
  1313.    LOCK_VARIABLE(sb_16bit);
  1314.    LOCK_VARIABLE(sb_midi_out_mode);
  1315.    LOCK_VARIABLE(sb_midi_in_mode);
  1316.    LOCK_VARIABLE(sb_dsp_ver);
  1317.    LOCK_VARIABLE(sb_hw_dsp_ver);
  1318.    LOCK_VARIABLE(sb_dma_size);
  1319.    LOCK_VARIABLE(sb_dma_mix_size);
  1320.    LOCK_VARIABLE(sb_sel);
  1321.    LOCK_VARIABLE(sb_buf);
  1322.    LOCK_VARIABLE(sb_bufnum);
  1323.    LOCK_VARIABLE(sb_recbufnum);
  1324.    LOCK_VARIABLE(sb_dma_count);
  1325.    LOCK_VARIABLE(sb_semaphore);
  1326.    LOCK_VARIABLE(sb_recording);
  1327.    LOCK_FUNCTION(sb_play_buffer);
  1328.    LOCK_FUNCTION(sb_interrupt);
  1329.    LOCK_FUNCTION(sb_rec_read);
  1330.    LOCK_FUNCTION(sb_midi_interrupt);
  1331.    LOCK_FUNCTION(sb_midi_output);
  1332.    LOCK_FUNCTION(sb_record_buffer);
  1333.    LOCK_FUNCTION(_mpu_poll);
  1334.  
  1335.    _dma_lock_mem();
  1336. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top