Multipak upgrade

What does an MPI do, and why does it have to be upgraded? 

Back in the day, small computer systems addressed everything as RAM. Great theory, but silicon was expensive in the eighties and a random subset of 16 address lines can be many logic gates added to the cost of every expansion card. To support cheap external hardware, computers of the day would provide 'slot select' signals. The card could use that, plus a few low order address lines for it's internal registers, and job done.

Apple had 4 slots, which covered a reasonable amount of expansion. The CoCo only had one, unless you add an external device like the MPI.

There are two output signals denoting a preselected address range.

CTS $C000 - $FDFF read only ROM software
SCS $FF40 – $FF5F read/write hardware


The CoCo also accepts two related inputs from ‘the’ external device.

CART A valid external ROM is present, run it.
SLEN Disable CoCo’s internal address decoding.

 

For a single device, simply connect SCS to the chip select for your hardware, and/or CTS to the chip select for your ROM chip. To auto run your ROM on startup, tie CART to the E clock. This lashup will ‘ghost’, in other words that low order address pattern will be repeated throughout the select range.

This is fine for one device, but what happens when two 'standard' expansion cards are plugged in? They stomp on each other, of course. And that is where  SLEN comes in. An external device can ask the SAM/GIME to kindly not put out the CTS and SCS signals. The full address is still present on A0-A15, but no shortcuts. The MPI also checks this signal, since it also deals in SCS and CTS and needs to know when to shut up. It does this job just fine on any model CoCo, nothing to see here.

But the ghosting problem hasn't gone away, it's just been relocated. First, we need to identify the CTS range $C000-$FDFF, which looks like this in binary:

  C000 11000000 xxxxxxxx
FDFF 11111101 xxxxxxxx


where all possible values in the xx positions will fall inside the range and can be ignored. For decoding work we only have to consider a range of 8 bit numbers.

The end of SCS is more expensive, 12 significant bits to puzzle out FF40-FF5F. Why not cut one more bit off for expansion? On a CoCo One or Two, this area is not used... and so, the MPI stops decoding at A5 so the SCS or read/write range is:

  FF40 11111111 010xxxxx Start of SCS
FF9F 11111111 100xxxxx End of MPI range
FF7F 11111111 01101111 MPI slot select


This a problem for CoCo3, which wants the FF9x range for the GIME. The original 'big' MPI were actively hostile, letting writes to $FF7x echo to the related address $FF9x. Luckily, the ‘big’ MPI have an easy fix, replace the socketed PAL chip.

Newer MPI are more subtle, they don’t echo writes themselves but do leave both active. This could have been a BFD, ASICs are not as easy to replace as PALs, even if there was a socket. But somebody spotted a workaround.

Address table bit 7 is only set when CTS is active, or we are in the no-no range &FF9x. So all we need to do is hijack the MPI’s internal select signal ‘ENBUS’ and disable it when CTS isn’t active and address bit 7 is high (one). As luck would have it, this hijacking can be done outside the ASIC chip with a simple trace cut.

This must be done inside the wonder world of active low signals. Logic gates compare the ones. Active low signals are not ones and cannot simply be OR’ed together. Instead of asking our original question ‘is CTS set or SLEN set or bit A7 = 0? you have to ask ‘is CTS not set and SLEN not set and bit A7 = not 0 ?

And then, a NAND gate flips the output to again be active low. So once a second input stage determines ENBUS is not set we can finally compare if ENBUS isn’t not set, CTS is not not active or SLEN is not not active or address A7 is not not zero. Resulting in an output ENBUS* signal with $FF9x chopped off that we can supply to the rest of the MPI on other side of the trace cut.

Simple.
-rick