brian@ucsd.EDU (Brian Kantor) (09/21/88)
If you're not a hardware type, this article may only be a bad temptation for you.... 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. When current 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 zero bit. 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! Brian Kantor UC San Diego "There is more harmony in films than in life." - Francois Truffaut P.S.: 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.
dmt@mtunb.ATT.COM (Dave Tutelman) (09/23/88)
In article <1160@ucsd.EDU> brian@ucsd.EDU (Brian Kantor) writes: >Recently I got interested in building a MIDI interface for an IBM >PClone.... >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: > ....<good description of minimum-change design of MIDI port> > >Software is something I'm still playing with, so I'll not include any >here.... >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. Bravo, Brian. A nice design. But you're right; commercial software doesn't stand a snowball's chance in hell of running on it. Which brings me to..... Some of us have built the BYTE MIDI board (Kubicky article in BYTE June '86), which shares that problem. We've been hacking our own code. I've designed a program interface (think of it as C functions or BIOS functions; both are available), intended for maximum portability among I/O boards. I'll be glad to send the specs for it (and perhaps even the source code) on request. FEATURES: - "Functional", non-hardware-specific MIDI I/O, like send_midi_byte or receive_midi_message. - Timer and timestamping built into the functions. Implementation can be on-board (Kubicky's board has an 8253 on it) or in software (Kantor's board doesn't). - The implementation in PC Assembler has isolated board dependencies in a few places; most of it should work with "any" board. I'd like to propose this interface as one we could use for any PD/Freeware/Shareware software that springs from this newsgroup. +---------------------------------------------------------------+ | Dave Tutelman | | Physical - AT&T Bell Labs - Lincroft, NJ | | Logical - ...att!mtunb!dmt | | Audible - (201) 576 2442 Work | | (201) 922 9576 Home | +---------------------------------------------------------------+