MIDI for the IBM PC
[Document Version: 1.00]
[Last Updated: Jan_1991]
Author: Brian Kantor, UC San Diego
Recently I got interested in building a MIDI interface for an IBM
PClone. A few years ago I'd have done for an S-100 system, but
since PClones are the current hardware-hacker's junk computer, it
seemed easiest to use one of them. Besides, they're cheap and easy
to fix when you fry one. Parts are everywhere.
Brief review of MIDI: Midi uses a serial asychronous protocol,
running at 31.25kbit (31,250 baud). It sends a 10-bit frame
consisting of a start bit, 8 bits of data (from LSB to MSB), and
a stop bit. It uses an optically-isolated receiver and a 5ma
current-sourcing transmitter in a current-loop configuration.
Circuits are simplex (i.e., each pair of wires has a defined
transmitter end [MIDI OUT/THRU], and a defined receiver end [MIDI
IN]). Unlike every current-loop interface ever designed since
Samuel F.B. Morse invented the land-line telegraph, MIDI idles in
the marking ("1","on") state with no current flowing, and indicates
a spacing ("0", "off") state by flowing current. (Yes, that means
that it's inverted from everybody else's concept of current loop
interfaces. Arrgh!) It uses 5-pin DIN jacks with the cable being
twisted pair inside a shield. DIN pin 2 is the shield, pin 4 the
+ side of the source, and pin 5 the - side. Pins 1 and 3 aren't
used, generally. The 8+2 bit frame is nearly identical to the
serial interface used for personal computer data communications,
although the electrical interface is quite different.
Being of un-sound mind (PUN!) and thin wallet, I decided to see how
I could build a MIDI interface for real cheap. Turns out that
PClone serial interface adapter boards seem to be a drug on the
market: there are lots of them out there for real cheap. So how
to adapt one to MIDI? Watch:
MIDI runs at 31,250 baud. You can't set a PClone async board to
that baud rate - the closest you can get is 38,400 or 28,800.
That's because the UART chip generates its baud rate by dividing
a 1.8432MHz clock signal by a sixteen-bit number [in a register on
the chip] to provide the baud rate clock at 16 times the actual
baud rate. (For example, 38400*3*16=1843200, or 28800*4*16=1843200).
Some Taiwan versions of the serial interface board use 18,432MHz
crystals and a divide-by-ten chip to get the 1.8432MHz clock, while
others just use a 1.8432 MHz crystal in the first place. 18MHz
crystals are cheaper or easier to get, I guess.
But if we change the baud rate generator clock to 2MHz, we can
divide by 4 to get 500KHz, which is just right - because it's 16
times the MIDI baud rate. So: rip out the 1.8432 MHz [18.432]
crystal and put in a 2.0 MHz [20 MHz] crystal. No problem: crystals
are about $2 at the electro-junk store, and those hybrid oscillator
modules that look like oversize tin chips are about $6. Real cheap.
All you have to do is know how to un- and re-solder. The 8250 UART
chip won't mind - its maximum baud rate generator clock frequency
is spec'd at 3.1MHz.
Ok, we've taken care of the baud rate. Now, the current loop.
Early PClone serial cards had a current loop interface available
by just reversing the large jumper header on the card (the small
one changed it from COM1 to COM2 when you reversed it), but it's
inverted from what MIDI wants, and later versions don't have current
loop anyway. So we'll have to build an adaptor.
The MIDI-OUT part is a breeze. RS232 swings from -12 to +12 on
most PClone cards, since those voltages are available inside the
machine. If we connect the - side of our PC-MIDI-OUT cable to
signal ground (pin 7 on the 25-pin connector), and stuff a diode
and a resistor in series between data out (pin 2) of the connector
and the + side of the PC-MIDI-OUT cable, we've got it. The plus
side of the diode (the end with the stripe on it) goes towards the
cable so that current flows in the MIDI-OUT cable only when the
port is at +12 volts, trying to send a zero. The diode is some
el-cheapo silicon type like a 1N914 or 1N4148, and the resistor is
470 to 680 ohms -- it's just there to limit the current to around
5 to 10 ma like a good MIDI interface should. Put a 5-pin DIN plug
on the other end of the cable, with the + wire going to pin 4, - wire
to pin 5, and shield to pin 2, and connect the shield on the PC end to
pin 1 of the DB-25, and you've got it. Voila! MIDI-OUT for your PC.
MIDI-IN is a bit more complicated, but only slightly. First, you
have to make sure that the serial card manufacturer provides + and
-12 volts on pins 9 and 10 of the 25-pin connector. Most do. If
not, they're certainly available on the card and you can install
some wires (use wire-wrap wire) to route them to the connector.
That taken care of, you need an opto-isolator chip. About $1 at
the electo-junk emporium. I used a 4N37 chip because I had one,
and it's a good choice, but almost any type with a phototransistor
output should work fine. Connect a 4.7Kohm resistor between pin
10 (- voltage) and pin 3 (data in) of the 25-pin plug on the serial
card. Connect the emitter lead (pin 4) of the chip to pin 3 on
the DB-25, and the collector lead (pin 5) of the chip to pin 9
(+ voltage) of the DB-25. Connect the + wire of the PC-MIDI-IN cable
to the anode (pin 1) of the opto-isolator chip, and the - wire of
the cable to the cathode (pin 2) of the chip. The way this works
is that the resistor keeps the serial card data in (pin 3) at -12
volts normally, which corresponds to an idle ("1") line.
flows in the MIDI-IN circuit, the LED in the opto-isolator lights
up, shines on the phototransistor, which switches on and provides
+12 volts to the data in of the serial card, which reads it as a
Wrap the whole thing in electrical tape or something to make it
sturdy, and you're done.
If you are one of those souls blessed with a 9-pin instead
of a 25-pin serial port, you'll have to figure out the pins for
yourself, and find some way to get + and - 12 volts out the back.
Maybe you could drill a hole in the card mounting plate and run
the wires out. Note that shorting the 12 volt supplies to ground
or to each other will probably fry something. Be careful!
Software is something I'm still playing with, so I'll not include any
here, except to show you how to set the baud rate to MIDI rate. Note
that BASIC isn't fast enough; you'll have to use some compiled or
assembled language that lets you frob with the ports directly. You've
only got ~320 microseconds to grab an incoming MIDI byte, so you can't
waste time. Note also that PC interrupts are really SLOW, so you may be
better off with polled port I/O.
This fragment of C code assumes that your interface lives at COM2 at
address 2F8 in the PClone. Clearly you could put it elsewhere.
outportb(0x2fb, 0x83); /* select baud rate divider latch */
outportb(0x2f8, 4); /* low byte of divider = 4 */
outportb(0x2f9, 0); /* hi byte of divider = 0 */
outportb(0x2fb, 3); /* deselect baud; 8-bit no parity mode */
From this point on, you can read port 2FD for the serial port status,
and read/write port 2F8 to receive and send MIDI data. The rest is up
to you. Don't fry anything expensive. Enjoy!
It's virtually certain that commercial MIDI software packages
can't use this interface, since it'll be at the wrong address at least.
Sorry 'bout that.