MIDIserver 200

 

Converting a DECserver 200 into a MIDIserver 200

For many years I thought about connecting MIDI equipment like an expander or something like this to one of my VAX machines running VMS. If you think that using a PC would be much more simpler, you are right, but using a VAX running VMS is much more fun! And - it is a system I am familiar with and I like to program - there is nothing like QIOs. :-)
The MIDI interface calls for a current loop interface and it would be fairly simple to build a small converter from RS-232 to current loop if MIDI would not use a rather unusual baud rate. It runs at 31250 bits per second instead of - say - 38400 baud or the like. This stems from the fact that 31250 baud can be easily derived from dividing a clock of, for example, 1 MHz by an appropriate integer factor or even a power of 2 if you are lucky. This was the reason to choose this odd transmission speed for MIDI equipment.
My first idea was to use a DLV-11J, this is a quad serial line interface card for QBUS systems. I intended to just change the clock generator but when I thought about having a VAX running next to my grand piano I shuddered - it would be too loud and too large to fit well into my living room. So I thought about building a baud rate converter using a small 68HC11 system but this was too much effort for a project like this.
Finally I thought about converting a DECserver 200 (this is an eight line asynchronous terminal server) to a MIDIserver 200. :-) The basic idea is the same as in converting a DLV-11J interface board. Just change the main clock generator and you are done. Opening a DECserver 200 reveals some interesting facts: It uses four DUARTs SCN 2681 which share a common clock line. Since the first port on a DECserver 200 is used as a console port for configuring and monitoring the device, I decided to modify the clock distribution cabling in a way that ensures that the first DUART (serving port 1) receives the normal clock while the remaining three DUARTs receive a new clock signal.
The internal clock signal driving the X1-input of the four DUARTs is a 3.6864 MHz square wave. Since the maximum baud rate which can be configured on the DECserver 200 is 19200 baud, the new clock frequency for obtaining 31250 baud has to be exactly 6 MHz. This is well beyond the maximum ratings specified in the SCN 2681 data sheet but I decided to give it a try.
In a first step I decided to separate the clock line of the first and the remaining three DUARTs as can be seen in the following picture (note that the wire with the white insulation was necessary only because I slipped with the cutting knife and destroyed a printed wire :-) ).

 

 

The original clock signal can be obtained from a 74F37 in the right corner of the main board (RS-232 connectors facing to you):

 

When I connected DUARTs two, three and four to a 6 MHz crystal clock generator and switched the DECserver 200 on for the first time I realized that it did not pass its self test routines. It identified ports three to eight as buggy and disabled them. Another test with a simple switch was more successful. During startup all DUARTs received the same (original) clock signal so the DECserver 200 passed its self test without problems. After completion of the test routines I flipped the switch so the DUARTs (except DUART one) received the new 6 MHz clock signal. Sending a text from a VMS machine via LAT to one of the ports connected to one of these DUARTs showed that the transmission worked flawlessly (despite the overclocking). The following picture shows the test environment of the device. On the left is an oszilloscope to monitor the clock lines, in the middle the modified DECserver 200 can be seen and on the right is an INTERVIEW 4500 serial line analyzer.

 

The remaining problem was how to get rid of the clock switch since it is not very comfortable being forced to flip a switch each time the device is powered up just to get it through its self test. The trick is to use the signal driving the LED D2 (the self-test-complete-LED) to control a 1-out-of-2 selector (74LS158) to select the original clock signal during self test (LED is off) and to automatically switch over to the new 6 MHz clock signal after the self test finished (LED on).

 

This small circuit worked very fine so the last thing to do was building a small current loop converter for one of the ports supporting 31250 baud. This driver consists of a 74LS14 as main driver circuit and an opto coupler for decoupling the MIDI input signal from signal and ground of the DECserver 200. The opto coupler can be seen in the lower middle of the picture below:

 

The following picture shows the MIDIserver 200 after completion. Note the MIDI cable leaving the case on the right - it ends in an 15 pin SUB-D plug. From there MIDI devices are connected via an adapter cable. On the left, next to the AUI-plug, the MIDI/NORMAL switch can be seen which is used to select between MIDI mode (MUX enabled) and normal operation as a simple DECserver 200.

 

The following picture shows all changes made to the DECserver 200 during the conversion:

 

And a simple program to play a few notes via the MIDIserver 200 (this was, infact, my very first test program :-) ):

  
#include<STDIO.H>
#include<STDLIB.H>
#include<MATH.H>
#define MIDI_DEVICE "LTA44:"

#define ON 1
#define OFF !ON

#define OK 0
#define ILLCHNL -1
#define ILLNOTE -2
#define ILLVELO -3
#define ILLSTAT -4

int switch_note (FILE **, int, int, int, int);

int main ()
{
    int note, akkord [8] = {50, 54, 57, 62, 66, 69, 74, 78};
    FILE *output_handle;

    if (!(output_handle = fopen (MIDI_DEVICE, "w")))
    {
        fprintf (stderr, "Unable to open device %s.\n", MIDI_DEVICE);
        return -1;
    }

    for (note = 0; note < 8; note++)
    {
        switch_note (&output_handle, 0, akkord [note], 10, ON);
        sleep (1);
    }

    for (note = 7; note >= 0; note--)
    {
        switch_note (&output_handle, 0, akkord [note], 10, OFF);
        sleep (1);
    }

    fclose (output_handle);

    return OK;
}

int switch_note (FILE **handle, int channel, int note, int velocity, int state)
{
    if (channel < 0 || channel > 15)
        return ILLCHNL;

    if (note < 0 || note > 127)
        return ILLNOTE;

    if (velocity < 0 || velocity > 127)
        return ILLVELO;

    if (state == ON)
        fprintf (*handle, "%c%c%c", 144 + channel, note, velocity);
    else if (state == OFF)
        fprintf (*handle, "%c%c%c", 128 + channel, note, velocity);
    else
        return ILLSTAT;

    return OK;
}

 

ulmann@vaxman.de

webmaster@vaxman.de