BeeBMIDI (Part 1)
Designer Jay Chapman describes the construction of E&MM's own MIDI interface for the BBC Model B home computer. There's also a test program to check your interface is working as it should do.
Co-designer Jay Chapman introduces BeeBMIDI, a build-it-yourself MIDI interface for the BBC Model B home computer.
BeeBMIDI is designed for connection to the 1MHz Bus on a BBC Model B Microcomputer or a suitably upgraded Model A. The interface described consists of four main areas: the MIDI current loop interface, the 6850 ACIA, the 1MHz Bus interface, and the power supply circuitry.
It is worth pointing out at this stage that most designs for microcomputer to MIDI interfaces are going to look very similar for two reasons. First, they should all be derived from the circuit specification given in the document MIDI Specification 1.0 published by the International MIDI Association (IMA) and reproduced in the first part of this supplement. Secondly, the basic requirement is to convert serial information on the MIDI connections into bytes of data understandable by the micro - as ACIA chips such as the 6850 do all the dirty work very nicely they tend to get used!
The serial to byte conversion, including the necessary timing, is handled by the Motorola 6850 Asynchronous Communications Interface Adaptor (ACIA). As far as the BBC Micro is concerned, the control and data registers associated with this ACIA are accessed as though they were ordinary memory locations - the ACIA is 'memory mapped'. The operation of this chip will be discussed a little later.
The 6502 CPU's data bus is connected straight through to the ACIA, and data can thus be sent to or from the ACIA as eight-bit bytes along lines d0 to d7, which are connected to pins 22 to 15 on the ACIA chip.
The ACIA chip is enabled by a combination of decoding address lines A0 to A7, and using the 1MHz bus NPGFC (Not PaGe FC) signal which goes low whenever memory page &FC is addressed (the indicates hexadecimal). The NPGFC signal is cleaned up, giving CPGFC (Clean PaGe FC, would you believe?) by one quarter of IC2, a 74LS75 four-bit bistable latch. This is required to avoid address decoding glitches caused by the difference in speed between the CPU bus (normally 2MHz timing) and the 1 MHz bus when the latter is not being addressed.
Having selected page &FC, the addresses within the page are decoded by IC3 (74LS30 eight-input NAND gate) and one of the inverters in IC5 (74LS04 hex inverters). These two gates, and the fact that pins 7 and 8 of the NAND are both fed logic 1's (ie. five volts), combine to give a six-input AND gate. This means that CS0 (Chip Select 0) will only be high if address lines A2 to A7 are all high, and as A1 is directly connected to NOT CS2, it must be low to enable the chip. A0 is connected to the Register Select (pin 11) so the bit pattern of the low order address byte is 1111110?, where ? selects between two registers in the ACIA (but see the full story in the software section!). The 'read/write' line is buffered by another IC2 bistable and enters the ACIA on pin 13.
For anybody feeling a bit confused, the previous paragraph means that you end up with the 6502 CPU seeing the ACIA as the two addresses &FCFC and &FCFD, and being able to specify whether a read or write is required.
The addresses chosen are within the 'User Applications' space allocated by Acorn in FRED (the Acorn name for the memory mapped I/O page) and this should ensure compatibility with their future products. Note that Acorn specify that any devices on the 1MHz bus should provide a 'through' connection of the bus so that further devices can be connected - this connection has not been provided in order to keep down cost and complexity. When you spend a couple of hundred pounds on a 1MHz add-on you can make sure it does have a 'through' connection and connect BeeBMIDI at the end of the chain...
Note that the NIRQ line of the bus has been connected to the ACIA (pin 7) so that advanced users can take advantage of interrupt handling. This might be particularly useful if several BeeBMIDIs were to be used at the same time.
One advantage of using the 1MHz bus instead of a user port is that we do not need to generate our own 31.25kBaud clocking for the MIDI serial data onboard, since this can be derived from the 1MHz signal available on the bus: the correct MIDI frequency is derived by dividing the 1MHz clock by 32.
The 1MHz clock signal connects to another of IC2's four-bit bistable latches, the latter being used as a buffer so that only one TTL load is driven by the bus line. The 6850 needs to synchronise with the 6502 CPU's memory accesses, so the buffered 1MHz is fed into pin 14 (the 'Enable' pin) of the 6850. This is actually to do with the Motorola 6800 series component timing and need not concern us here. The same signal is divided by two by one of the D-type flip-flops in IC4, a 74LS74 dual D-type flip-flop package. The resulting 500kHz clock is fed into the receive (pin 3) and transmit (pin 4) clock inputs of the ACIA. This 500kHz clock is divided by 16 in the ACIA to give the time-per-bit, thereby giving the required MIDI serial data clock rate of 31.25kBaud.
The transmitted serial data from the ACIA is sent via the two inverters (part of IC5) providing sufficient drive current for the MIDI Out connection. The MIDI In connection is fed into the receiver side of the ACIA, following what is effectively a current-to-voltage conversion provided by the optoisolator, which also prevents the formation of ground loops.
The power supply will not be described in detail since it really is quite straightforward. Links have been provided so that either six volt AC or nine volts DC can be used to power the board. Note that the power has not been taken from the BBC micro as this is contrary to the 1MHz bus specification. If you have no disk drives, ROM boards, etc., you could dispense with the power supply and use the BBC's five-volt supply connected in place of C5. If you wish to use six volts AC, link L2 should be made and link L1 broken. Otherwise, link L1 should be made, L2 broken and nine volts DC connected across pins H and I (H is positive).
Construction is fairly simple.
A single-sided board is used to keep the cost down, hence the usual problem that connections need to be made across the 'bus' tracks on the board. This problem is solved by extensive use of links which are easily made by using insulated single-strand copper wire. Vero pins, shown lettered A to K on the drawings, should be fitted at this stage. Once these are in place, the diode, decoupling capacitors and resistors should be soldered in place, observing correct polarity for the diode.
Next, the sockets are added, followed by the electrolytic capacitor C1, the regulator, and the bridge rectifier - all of which should be connected carefully, preserving orientation.
The MIDI In and Out DIN sockets can now be connected. Note that the MIDI Out socket has pin 2 connected to pin A on the board via the shield of the connecting cable: this latter can be any shielded cable with a minimum of two cores. The MIDI In socket does not have any shield connection to the board, as any cable connecting to it will be shielded from the far end.
The power supply should be tested before the ICs are inserted, to see that the voltage is correct and that power is available at all the IC sockets. The ICs can now be inserted again, paying attention to the orientation in each case as well as the position in the eight-pin DIL socket of the six-pin optoisolator.
Connection from the BBC Micro's 1MHz bus to the board is made with a 34-way ribbon cable, fitted at both ends with 34-way female header Insulation Displacement Connectors (IDCs). On the board a male right-angled PC-mounting IDC is used. These connectors can be fitted to the cable with the help of a vice and a little care - when making up your cable, make sure the polarising bumps (if any) match, otherwise the cable will always be twisted when in use. A cable length of no more than one metre should be used.
Once built, the board can be tested with the 'Exerciser' program discussed below.
At this point you should type in and save a copy of the 'MIDI Interface Exerciser' program. We'll use this program to test the interface and to explain the basic software techniques employed in driving the interface.
Connect the BeeBMIDI Interface to the BBC Micro's 1MHz bus socket and to whichever form of power supply you're using. Use a suitable DIN-to-DIN cable to connect the MIDI In and MIDI Out sockets on the interface. Switch on the computer and the interface and load and run the MIDI Exerciser program.
The program transmits the full sequence of possible bit patterns in a byte (values 0 to 255) via MIDI Out, and after each byte is transmitted waits to receive a byte via MIDI In. Having connected MIDI Out to In we should find that the byte received is the same as the last byte transmitted.
If the two bytes are not the same then there is something wrong with the interface. When this happens to me it's usually because (a) I forgot to turn the interface power supply on or (b) a wire has pulled off one of the MIDI sockets because I haven't boxed the interface yet and the wires aren't supposed to take the strain!
If the Exerciser shows that the interface is working but you still have no luck making it talk to your synth, make sure you haven't wired the MIDI In and Out sockets up 'mirror image'. If you have, they'll still talk to each other with no problems but they won't be able to talk to the rest of the MIDI world...
The subject of what information you should be transmitting to and receiving from your MIDI instruments is covered elsewhere in this supplement. Here we are concerned with the basics of simply transmitting and receiving over MIDI - in other words, how we drive the 6850 ACIA.
You'll recall from the Hardware section above that the connections between the BBC Micro's 1MHz bus and the 6850 give essentially two locations (&FCFC and &FCFD), that we can read and write and a 500kHz timing signal. What follows is a description of how the software makes use of these hardware facilities.
Lines 80 to 110 of the program set up some names for the four registers we use in the 6850 ACIA. Although the control and status registers are addressed at the same location (&FCFC), they are really two different registers - the read/write line is used to select between them. In other words, we get the contents of the status register when we read from &FCFC and we set the contents of the control register when we write to &FCFC. Location &FCFD is treated in the same manner to give a write-only transmit register and a read-only receive register.
Various bit patterns are written into this register to do different things. The pattern '00000011' (hexadecimal &03) causes the ACIA to perform a 'Master Reset': the chip stops whatever it was doing and goes into a stable 'clean' state in preparation for being configured by the controlling CPU. In the Exerciser program, &03 is written into the control register in line 160. The Acorn BASIC syntax is a little different from Microsoft-type BASIC, so perhaps I should explain that '?address = number' is the equivalent of 'POKE address, number' on some other micros.
Following the Master Reset, we configure the ACIA by writing the pattern '00010101' (hexadecimal &15) into the control register in line 210 of the program. The sets of bits that interest us here are the two low-order bits CR1 and CR0 ('01') and the next three bits CR4, CR3 and CR2 ('101').
As we have already seen, CR1 and CR0 can be used to specify a Master Reset when they are both on (ie. '11'). Otherwise they are used to specify by what factor the incoming transmit and receive clock frequencies should be divided before being used. In our case we have an incoming frequency for both transmit and receive of 500kHz. We require division by 16 to give the MIDI specified 31.25kHz, so we choose pattern '01'. Patterns '00' and '10' would have given divide by 1 and 64 respectively.
Bits CR4, CR3 and CR2 are used to specify the Word Length, the Parity and how many Stop bits are to be used. To cut a long story short, the MIDI specification insists on one start bit - which the ACIA assumes anyway - eight data bits, no parity bit (we haven't time to go and ask for the byte again if we get a bad one) and one stop bit. The configuration pattern '101 ' in CR4, CR3 and CR3 does the trick.
Four of the bits in this register are of direct interest to us: SR0 (Receive Data Register Full or RDRF); SR1 (Transmit Data Register Empty or TDRE); SR4 (Framing Error or FE); and SR5 (Receiver Overrun or OVRN).
SR4 and SR5 are both concerned with errors that have occurred whilst trying to deal with incoming data bytes, so it may be important to check these bits in any programs you write. Notice that there are no error bits associated with transmission. Provided your program handles the byte transmission in the proper maner (see under Transmit Register below) the byte will be transmitted correctly.
A Framing Error (FE) occurs when a start bit is noted coming in (from MIDI In in our case) and the corresponding stop bit is not found immediately after the end of where the ACIA times the data bits to be. Typical reasons for FEs would be that the transmit speed of the remote ACIA and the receive speed of this ACIA don't match, or that bits are being corrupted somehow during transmission. In general, though, you shouldn't be greatly troubled by FEs.
Receiver Overrun (OVRN) errors, on the other hand, are something you may very well need to worry about. What happens here is that the ACIA receives a byte before your program has managed to pick up a previously received one: the original byte is overwritten and you've lost it! The usual reason this occurs is simply because your program has taken too long over processing a particular received byte. In fact, this is precisely why BASIC is not used to write MIDI input software (eg. for real-time keyboard input or program dumps), as there is only about 0.0003 of a second, on average, to deal with each byte received in the worst case, and interpreted BASIC just isn't fast enough. The Exerciser program leaves long gaps between each byte and so sidesteps this particular problem.
In line 400 of the program, the byte to be transmitted is 'poked' into the transmit register. Immediately the write into the register is finished the ACIA transmits the byte serially at 31.25kBaud to MIDI Out.
Of course, it takes time to transmit the byte - one start, eight data and one stop bit at 31.25kBaud need 320 microseconds - so we must be careful not to try to transmit another byte until this one has gone (corresponding to the OVRN error on receive). To be completely accurate, it's important not to 'poke' another byte into the Transmit Register until the current contents have been transferred to the Transmit Shift Register inside the ACIA.
Once there is one byte starting transmission and a second byte in the Transmit Register, the process has to wait: Program Lines 330 and 340 are responsible for waiting if it is necessary. The program will loop at this point until '?status% and &02' is non-zero. '?address' in Acorn BASIC corresponds to 'PEEK(address)' in other BASICS, so '?status%' is reading the contents of the ACIA status register. &02 is the bit pattern '00000010', so the 'and &02' isolates the SR1 bit for us. In other words, the result of '?status% AND &02' is '00000010' if SR1 is set ('1') and '00000000' if SR1 is off ('0').
So, if SR1 (the Transmit Register Empty status bit) is set, we can go ahead and poke the next byte to transmit into the transmit register. If SR1 is zero - and therefore '?status% &02' is zero - we must wait.
Lines 450 and 460 organise the waiting if the 'Receiver Register Full' bit, SR0, is set. The &01 is the bit pattern '00000001' and the '?status AND &01' works in a similar manner to that described above. Once the Receive Register is known to be Full we 'peek' the byte held therein into the integer variable Rx_byte% in line 480.
The program goes round in a nerver-ending loop from line 280 to 600. Line 260 starts the value of the byte to be transmitted (held in the integer variable Tx_byte%, off at 0), and line 580 increments this byte value. The MOD 256 ensures that the value stays in the 0 to 255 range. Lines 370 and 500 tell you what was transmitted and received respectively on each trip round the loop. The delay loop in line 530 is there so that you've got time to read the program output!
Having connected BBC Micro, BeeBMIDI Interface and MIDI-compatible synth(s) - what next? Well, you need some software to drive all the hardware!
The July issue of E&MM will feature an article on some elementary BBC BASIC routines that should get you interested in the idea of doing your own programming, as well as ensuring that your interface starts getting used as soon as possible after you've constructed it. A little later on, we'll also be presenting an E&MM exclusive software package that'll enable you to use BeeBMIDI as a fully-polyphonic, eight-channel MIDI sequencer. Until then, happy MIDI soldering...
MIDI Supplement - Part Two
Gear in this article:
Feature by Jay Chapman
mu:zines is the result of thousands of hours of effort, and will require many thousands more going forward to reach our goals of getting all this content online.
If you value this resource, you can support this project - it really helps!
Please note: Our yearly hosting fees are due every March, so monetary donations are especially appreciated to help meet this cost. Thank you for your support!