74LS612 - Memory Management Unit
A way to expand your Commodore 256 times its original size.
DISCLAIMER
Copyrights
The 612 outputs twelve addresslines of which four (can) reflect the state of the four originally attached addresslines. The PLA and 128MMU only output ChipSelect-lines. This is one of the two major differences between the 612 and these two C= ICs: the 128MMU and PLA have onboard decoders.
The 612 has 16 registers of 12 bits each. The normal procedure is to address these registers using the four most significant addresslines; in case of a 6510 the addresslines A12..A15. Four bits of the output can be used to replace the original four addresslines, the other eight bits to form the extra eight addresslines. Every bit can be programmed as the user wishes, meaning that the four bits reflecting the original addresslines can completely differ with the original values. Reconfiguring the original addresslines gives you the ability to re-arrange the original configuration of the memorymap. In this way you could swap the range $8000/$9FFF and $E000/$FFFF in a C64 to test a new Kernal-ROM. In the original system the reset-procedure sets all the bits of address 1 which means switching to ROM ie. disabling the RAM under the ROM. With the MMU the ROM is enabled at $8000 and does not affect the new Kernal in RAM.
But a remark is here on its place: reconfiguring the original memory map does not mean that you are now able to place the CHARROM at $2000 and the I/O on $4000. With the MMU you move addressranges, not specific hardware. In the above example of swapping the Kernal it also means there is no RAM under the new Kernal. So you cannot test a new Kernal with a program which normally uses the RAM under ROM. In this case the program will overwrite the Kernal for sure with all devastating effects!
The moment you re-arrange the internal configuration, you have to take care of one important thing: make always sure you have access to the MMU! The reason is very simple: once you have placed the MMU out of the picture, you won't be able to change the configuration anymore and you are stuck with the momentary one for "the rest of your life".
Why do I use a 3032 and not a C64 in the above example? Two reasons:
74LS610, 74LS611 and 74LS613.
Memory-part
Fooling the original system
I/O-part
What is it?
The 612 is an MMU, Memory Management Unit, that enables you to expand your system with 8 extra addresslines. Notify the fact that I use the word "system" and NOT processor. The processor itself won't be 'aware' of those extra addresslines at all.
Availability
Nick Coplin had some ideas for using the 74LS612 only to find out that they are hard to get. The ones I have I got by recycling old PC motherboards but I cannot expect everyone having a load of old motherboards for scrapping. So I decided to make a MMU of my own.
How does a MMU work?
If you own a C64 or C128 then this is easier to understand. Both machines have at least 64 KB of RAM, 4 KB of I/O and at least 20 KB of ROM. But the 6510 and 8502 have a 16 bit addressbus only capable of addressing 64 KB. How do these numbers match? A more experienced programmer knows that he can read the contents of the RAM "under" the BASIC-ROM but has no access to that ROM at the same time: it is either RAM or ROM but not both! The same situation occurs with the I/O, CHARROM and the under laying RAM: it is either this or that but not all (or in this case not even two out of three). The C128 has 128 KB of RAM but if we want to read the contents of address $3887 in Bank 1, we are not able to read the contents of the same address in the other RAM-bank, Bank 0.
A more experienced user knows that it are the PLA and 128MMU which give the C64 and C128 the ability to handle more memory then the processor is capable of. He also knows that he has to switch the banks to be able to read/write the other parts of memory.
The 74LS612 does about the same but is much more flexible: it does not only give you the capability of bankswitching but also allows you to decide where which part of the memory should show up.
How do these 8 extra address lines fit in the system?
The C128 has 128 KB of RAM, 4 KB of I/O and a lot of ROM. If everything had to be connected to a regular addressbus, we at least needed two extra
addresslines. And the C128 does not have these lines. Or does it?
Yes, it does but we don't have access to them. In case of the 128MMU they are inside the MMU itself. In case of the PLA the outputs of the onboard port of the 6510/8502 function as the extra addresslines. In other words, this means that the user/software controls the state of these extra lines by means of one or more registers and not the processor.
The 74LS612 does not have these decoders. It only provides address lines like if it was a CPU. The decoders that translate the address to the chip select lines must be added by the user. Another difference is that the behaviour of the 128MMU and PLA has been pre-programmed in the factory and cannot be changed. But the user can program the behaviour of the 612 any time.
An idea how to use the MMU.
The extra eight lines can be used to add extra memory (RAM, ROM) or I/O in any way you want. One idea what I have in mind is to connect a complete 1541 to my 3032 by means of a small interface which replaces the original 6502 of the 1541. This interface is addressable from $01000 to $01FFFF. Now I can reconfigure my 3032 in such a way that the 6502 sees the range $010000/$011FFF of the 1541 on its own $0000/$1FFF range and its own range $004000/$007FFF as $C000/$FFFF. In this way you comfortably can test a new Kernal for the 1541. (The originator of this idea is Andre Fachat, Leipzig, Germany)
The above example is one of the exceptions. The range $2000/$BFFF is not used by the 1541 so we could arrange the memorymap in such a way that the I/O-part of the 3032, $E000/$E7FF, shows up at $4000. We now could send a small PRG to the 1541 and execute it in the buffer to reprogram the MMU but I think that pushing the RESET-button is a much quicker solution.
Pinouts
+---------------------+
RS2 -+ 1 40 +- +5V
| |
MA3 -+ 2 39 +- MA2
| |
RS3 -+ 3 38 +- RS1
| |
/CS -+ 4 37 +- MA1
| |
/STROBE -+ 5 36 +- RS0
| |
R/W -+ 6 35 +- MA0
| |
D0 -+ 7 34 +- D11
| |
D1 -+ 8 33 +- D10
| |
D2 -+ 9 32 +- D9
| |
D3 -+ 10 31 +- D8
| 74LS612 |
D4 -+ 11 30 +- D7
| |
D5 -+ 12 29 +- D6
| |
MM -+ 13 28 +- NC / C (see text)
| |
MO0 -+ 14 27 +- MO11
| |
MO1 -+ 15 26 +- MO10
| |
MO2 -+ 16 25 +- MO9
| |
MO3 -+ 17 24 +- MO8
| |
MO4 -+ 18 23 +- MO7
| |
MO5 -+ 19 22 +- MO6
| |
GND -+ 20 21 +- /ME
| |
+---------------------+
Pin functions:
D0 through D11 = Connection to the databus when programming the registers
RS0 through RS3 = Connection to the addressbus when programming the registers,
normally A0 through A3
R/W = Read, active (H) and Write, active (L)
STROBE = input to enter data into chosen register, active (L)
CS = ChipSelect, active (L)
MA0 through MA3 = input, to be connected to the addressbus of the processor.
These inputs choose an internal 12-bits register.
MO0 through MO11 = The generated addresslines
MM = Map Mode input. When (H), MO8/MO11 reflect MA0/MA03 and
MO0/MO7 are (L). When (L), MO0/MO11 reflect the 12 bits of
the chosen register.
ME = When (H), MO0/MO11 are tristate else active.
NC = Not connected.
The 610 is like a 612 but has an extra 12 bits latch. So with the 610 you can freeze the output as long as you want. This is archived with an extra inputline at pin 28, C (= Clock). A (H) on this input will the 610 cause to behave like a 612, a (L) freezes the configuration.
The 611 and 613 are the Open Collector versions of the 610 and 612.
The 12 bit registers of the 74LS612 - part 1
The intention is to use the MMU in combination with a 65xx based Commodore and as you know the 65xx's are all 8-bitters. This means we either have to disregard 4 bits or use a trick to be able to use all 12 bits. In the first case we are still able to address up to 1 MB of memory or I/O. If you still want have those extra 4 bits then a simple 74LS573, 8-bit latch, can do the trick. Of course you'll need a decoder for this 573. But as you need one for the MMU as well, it won't be that much difficult to combine them into one decoder. (for more details, see part 2)
Connecting the MMU to a 6502.
Connecting a MMU to a 6502 can be split up in two parts anyway:
If you only want to reconfigure your system within its own 64 KB, then you only have to "cut" the addresslines A12 through A15 and to place the MMU in the created gap. Practically this probably means you replace the processor by a small circuitboard with onboard the original processor, the MMU and some logic to perform I/O-operations with the MMU.
If you want to use the extra addresslines as well, you have to take care of the fact that the original hardware does not know of the addresses above $0FFFF. So for any decoder on the original system reading from/writing to $1C000, $2C000 or any address above $0FFFF is equal to reading from/writing to the address $0C000. There are two solutions for this problem:
Include the original decoder
The C64 uses an 82S100 PLA as decoder. This IC has a CS-line of its own but it is tied to Ground. Tying this line to a decoder, which decodes the addresslines above A15, solves the problem.
Sometimes the above solution is impossible due to the way the decoding is done. In case of the 8032 the range from $8000 to $FFFF is decoded by a 74LS154. But the range below $8000 is decoded by gates. This simply means that you have much more soldering to do.
With "fooling the system" we force the original system to read a safe address during the time the processor in reality is handling an address above $0FFFF. AFAIK a safe address for all Commodores is $FFFF. But reading implies outputting data, which we have to shield from the processor. This can be realised by using a buffer like the 74LS245. The fake address is realised by placing buffers in the addresslines between the original system and the processor/MMU. Using $FFFF has the advantage that we only need some pull-up resistors to generate this address the moment the bus is disabled.
Another decision to be made is where to place the addressdecoding of the MMU in the memorymap: behind or before the MMU itself. If you place it before the MMU it always will be accessible but the disadvantage is that it can get in the way when there is a need to remap certain areas to the area the MMU occupies. If you place it behind the MMU and you make a mistake with programming the MMU, it is possible you cannot access the MMU anymore meaning you are stuck with the momentary configuration unless you reset your system.
Enabling the MMU.
Negating the "Map-mode" -input enables the function of the MMU. So we need at least a programmable 1-bit register. But it is a MUST that its output always is (H) after a reset. A 74LS74 could do the trick. Connect its Preset-input with the resetline, the data-input with a dataline and clock-input with an active (L) chipselect-line. If you intend to use all 12 bits, this 74 can placed parallel to the used 573.
The 12 bits registers of the 74LS612 - part 2
We already know we have to provide four extra databits for the MMU. We also need a bit for enabling the MMU-mode. As said a 74LS573 could do the trick but only using a 573 means we cannot check in one or another way what we actually have written to the MMU. We could add a 74LS541 buffer to solve a part of the problem but in that case I propose to use a CIA, PIA, VIA, PIO or other equivalent type of IC. Which type you use partly depends on the processor used in the system.
One advantage of using such IC is that you have much more functionality then when using the 573/541 combination. Another advantage is that one I/O-line can be used for steering the "Map-Mode"-input of the MMU. As example I'll use the 6522 VIA from now on.
Now we are able to read the data written towards the MMU but we are still not able to read the contents of all bits of the 16 registers of the MMU. Luckily I found a solution where we only need an extra 573 and 04. The in- and outputs of four bits of the 573 are connected to the four I/O-lines responsible for the four extra bits of the MMU. The data on these lines is latched every time the /CS-input of the MMU is enabled (the 04 inverts this CS-signal to the right level for the clock-input of the 573). An I/O line of the 6522 takes care of dis/enabling the output of the 573.
As after a RESET of the system all the I/O lines have been switched to inputmode, a resistor should take care of pulling the MM-input (H), disabling the map-mode in this way. Another resistor must take care of disabling the output of the 573.
Extra functionality's of the 6522
I also have another reason to use the 6522. I intend to use the 65816 instead of the 6510 (C64) or 8502 (C128). But these processors have an onboard I/O-port which the 65816 lacks. The 6522 can supply this port.