Appendix 2: Non-MPU-401 MIDI Interfaces

George Logemann and Roger Dannenberg

CMT has drivers for several non-MPU-401 MIDI interfaces for IBM-compatible personal computers. Under DOS, there is no standard MIDI device driver interface, and CMT accesses MIDI interfaces directly through I/O instructions. CMT is not smart enough to detect your device type automatically and call the appropriate interface routines. Instead, the proper interface routines are selected manually and linked with the CMT library cmtlib.lib. All CMT programs in turn are linked with cmtlib.lib. These programs will only work with one particular type of interface, but you can re-link to make new versions that work with different interfaces.

A further restriction is that these alternative interfaces are only provided for users of Microsoft Quick C. We suspect that the files may work with other compilers, but we have not tested all the permutations. The approach describe in Section ``Sound Blaster Configuration'' should work with all compilers.

The supported non-MPU-401 devices are:

For convenience, also a dummy interface has been created, to allow testing of software without any interface. This can be useful; e.g., adagio with a dummy interface will allow the user to convert .gio files to .mid format.

In order to support all of these possibilities, the idea is to replace mpu.c (that handles MPU-401 and lookalikes) with a module that replaces mpu.c function calls (e.g., to send and receive data, to reset, etc.) with calls similar in function but of the same name (e.g., to send data, one uses mPutData(); this is an entry in mpu.c that will be replaced by one in each of the other modules). Thus, only cmtlib.lib is modified, allowing applications to be rebuilt with the same make file and configurations of object files.

Please note that Voyetra and Keytronics supply proprietary drivers and other software that obviously CMT cannot provide due to copyright restrictions. Please contact the manufacturer for their interface software. The Sound Blaster protocol is known publicly and therefore can be supported by CMT. (And Sound Blaster v4.xx cards work with the normal MPU-401 drivers in CMT; see Section ``SoundBlaster and MPU Compatible Interfaces'').

The modules required for the various interfaces are (note that file.[ch] means file.c, file.h):
InterfaceSupplied with CMTProprietary from manufacturer

Sound Blastermpusb.[ch],
revs. 1.xx,qmpusb.bat
2.xx, 3.xx

qvoyvapi.batvapi.h, cvapil.obj



In order to construct a cmtlib.lib for an alternative interface, build a new cmtlib.lib with qcmtlib.mak. (Recall that we only include support for Quick C.) Then run the batch (.bat) file indicated above. The batch file will modify cmtlib.lib by replacing the old mpu.obj code with code for a different interface.


  1. The Sound Blaster interface assumes base address 220 and interrupt level 5 by default. These can be overridden in the environment with variables MPUBASE and MPUIRQ respectively.
  2. Other than Sound Blasters version 4.xx, which can support MPU-401 lookalike registers, Sound Blasters have two other modes. Sound Blasters 1.xx thru 4.xx can employ "Normal" MIDI I/O mode, which mpusb.c performs by default. In addition, Sound Blasters 2.xx thru 4.xx can employ "Uart" MIDI I/O mode, which is invoked in mpusb.c by defining MPUUART=1 in the environment.
  3. If you use voyvapi, you can support regular MPU-401's as well by loading in place of See the Voyetra documentation for details.

Another Option for Sound Blaster Users

Here, we discuss a simpler way of supporting Sound Blasters 1.xx through 3.xx by replacing mpu.c for the MPU-401 with an "mpu.c" for the Sound Blaster. Section ``Default MPU-401 Configuration'' describes the default configuration for the MPU 401, and Section ``Sound Blaster Configuration'' describes the mpu.c replacement for the Sound Blaster.

Default MPU-401 Configuration

As released with CMT, mpu.c contains code for an MPU-401. Mpu.obj is contained in cmtlib.lib, which is in turn linked with CMT applications.

Mpuok.c is a copy of mpu.c. In case you lose the original mpu.c, you can copy mpuok.c to mpu.c and rebuild cmtlib.lib via qmaklib.mak.

By default, the standard mpu.c assumes the following:

To override defaults, in environment set:

Sound Blaster Configuration

Mpusb.c is modified from mpuok.c. You can copy mpusb.c to mpu.c and build cmtlib.lib via qcmtlib.mak. The resulting programs will not work with MPU-401 look-a-likes.

Mpusb.h supplements mpu.h. Do not change either mpusb.h or mpu.h.

By default, mpusb.c assumes the following:

Use the environment to override:

More Information on SoundBlasters

There are many flavors of SoundBlaster (at least eight), but for our purposes there are three classes:

The Pro series have two modes of MIDI I/O, one compatible the original series, another that is new to the Pro series. Both modes use DSP register locations, not at all like the MPU-401's; both require a special reset routine unrelated to MPU-401.

The difference between the two Pro modes is that the original one, called "Normal" requires status changing, i.e., turning off interrupt-driven input when you want to output, and requires outputting two bytes for every MIDI byte (essentially an escape byte to route the following byte to the MIDI interface). The other mode, called "Uart", does not work on the originals and does not co-exist with 8-bit DMA sound, but requires no status change and no escape byte.

There are a lot of changes needed to mpu.c, so George Logemann created an alternate version of mpu.c called mpusb.c that does both Uart and Normal protocol. Normal is done by default since that is common to all SoundBlaster's (so far).

Defining MPUUART uses Uart mode; this should be a little faster than Normal mode. mPutCmd is now useless and does nothing so that you do not have to change midifns.c when you switch from mpu.c to mpusb.c.


You can build versions of CMT with Quick C for various interfaces. There are two basic approaches. One is to alter the cmtlib.lib library file with code that was written specifically for different interface hardware. The other is to replace mpu.c with alternate versions. In general, you can adapt CMT to other hardware by supplying all the entry points mentioned in dummyif.c.

A comment: this would all be simpler if the mpu.c functions were included in a device driver. Then, you could simply install the right device driver and applications would run with different devices without recompilation or relinking.

Previous Section | Next Section | Table of Contents | Index | Title Page