*BSD News Article 87537


Return to BSD News archive

Newsgroups: comp.unix.bsd.freebsd.misc
Path: euryale.cc.adfa.oz.au!newshost.carno.net.au!harbinger.cc.monash.edu.au!munnari.OZ.AU!news.ecn.uoknor.edu!feed1.news.erols.com!howland.erols.net!news.sprintlink.net!news-peer.sprintlink.net!uunet!in2.uu.net!199.172.62.14!world!indra.com!tim
From: tim@indra.com (Timothy W Butler)
Subject: SoundBlaster 16 Vibra 
Message-ID: <E4n5DF.D7E.0.net@indra.com>
Organization: Indra's Net - Public Internet Access
Date: Mon, 27 Jan 1997 00:29:39 GMT
Lines: 160
Xref: euryale.cc.adfa.oz.au comp.unix.bsd.freebsd.misc:34553


  I've been banging my head against the kernel all weekend trying to 
  get my SoundBlaster 16 (Vibra) MIDI device to work. I _finally_ 
  figured it out.

  First of all, I am a kernel, /dev/audio, sound-card newbie so 
  sorry if some of this sounds obvious to you. I certainly learned a lot
  along the way.

  Synopsis
  ========
  Once I realized that I owned a SoundBlaster 16 _VIBRA_ and not just 
  a vanilla SoundBlaster 16, I was able to find sources to configure
  the MPU-401 UART MIDI interface base I/O address.  The "Vibra" flavor
  of the SB16 requires this base address to be configured in software,
  which the FreeBSD releases up to 2.1.6 don't do. The SoundBlaster manual
  states that the base I/O address defaults to 0x330, but I found
  that on a cold boot, the card came up in an undefined or disabled state. 

  You can tell if your SoundBlaster 16 is a Vibra if: 
  1. The big chip in the middle of the board says "Vibra"
  2. You don't have any jumpers to configure your MPU base I/O address.

  My symptoms were startup messages that looked like:

-|sb0 at 0x220 irq 5 drq 1 on isa
-|sb0: <SoundBlaster 16 4.13>
-|sbxvi0 at 0x0 drq 5 on isa
-|sbxvo0: <SoundBlaster 16 4.13>
-|sbmidi0 not found at 0x330
-| opl0 at 0x388 on isa
-| opl0: <Yamaha OPL-3 FM>

  When the sbmidi message should have looked like this:

-|sbmidi0 at 0x330 on isa
-| <SoundBlaster MPU-401>

  Here is what I did:
  ===================

  Configure the kernel
  --------------------
  Edit /sys/i386/conf/MYKERNEL (or whatever your kernel configuration
  file is named).

  Here are the entries that pertain to audio devices:

-|controller      snd0
-|device sb0      at isa? port 0x220 irq 5 drq 1 vector sbintr
-|device sbxvi0   at isa? drq 5
-|device sbmidi0  at isa? port 0x330      
-|device opl0     at isa? port 0x388 conflicts
-|options "SBC_IRQ=5"     
-|options "SBC_DMA=1"
-|options "SB16_DMA=5"
-|options "SB16MIDI_BASE=0x330"
-|options "SB16_VIBRA"

  Most of this is typical.  I didn't have any IRQ or I/O address 
  conflicts, although my system behaved like there was a conflict 
  with the sbmidi0 port 0x330.

  I added the options like the LINT config file and the 
  /sys/i386/isa/sound/sound.doc suggested.

  I MADE UP MY OWN OPTION called SB16_VIBRA which is described later.

  To other newbies:
  I didn't realize immediately that I could add
  the 'device opl0' to my config file.  This is the fm synthesizer device
  that lets you play midi files with the 'playmidi -f' command. 
 
  Hack the file /sys/i386/isa/sound/sb16_midi.c
  ---------------------------------------------

  You will make three changes:

  1. Add a function, 'sb16_set_mpu_port',  that initializes the 
     Vibra's MPU I/O base address. The source for this function
     comes from the latest sound device sources for Linux.
     ftp://ftp.4front-tech.com/ossfree.

  2. Call 'sb16_set_mpu_port' from the function 'probe_sb16midi' .

  3. Conditionally compile the above changes with #ifdef SB16_VIBRA.

  Here is what the last part of the hacked sb16_midi.c looks like.
  Unless you declare 'sb16_set_mpu_port' ahead of time, make sure it
  comes before 'probe_sb16midi'.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#ifdef SB16_VIBRA
static void
sb16_set_mpu_port (struct address_info *hw_config)
{
/*
 * This routine initializes new MIDI port setup register of SB Vibra (CT2502).
 */ 
  unsigned char   bits = sb_getmixer (0x84) & ~0x06;  

  switch (hw_config->io_base)
    {   
    case 0x300:
      sb_setmixer (0x84, bits | 0x04);
      break;

    case 0x330:
      sb_setmixer (0x84, bits | 0x00);
      break;

    default:
      sb_setmixer (0x84, bits | 0x02);    /* Disable MPU */
      printk ("SB16: Invalid MIDI I/O port %x\n", hw_config->io_base);
    }
}

#endif

int
probe_sb16midi (struct address_info *hw_config)
{
  int             ok = 0;
  extern int      sbc_major;

  if (sbc_major < 4)
    return 0;			/* Not a SB16 */

  sb16midi_base = hw_config->io_base;

#ifdef SB16_VIBRA
  sb16_set_mpu_port(hw_config);
#endif

  if (sb_get_irq () < 0)
    return 0;

  ok = reset_sb16midi ();

  sb16midi_detected = ok;
  return ok;
}

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


 Recompile the kernel
 --------------------

 cd /sys/compile/MYKERNEL; make; make install

 Make sure your read the FreeBSD handbook on recompiling the kernel.
 Make sure you have a backup.  Remember that a backup kernel is stored 
 in kernel.old so you can recover when your new kernel won't boot. 
 Also beware that if you do 'make install' twice, your old good kernel
 will be gone (haven't done that yet!).


 -tim