I want to add more devices to my computer, but there’s a problem – I don’t have any where to put them in my address space.
Well, actually – yes I do. I have an entire 16KB block (from &8000 to &BFFF) which is currently mapped to the 6522 … but that device only requires a fraction of that space. I need to evolve my address-decoder logic to make provision for more devices.
Here is a diagram showing the memory map of my computer so far:
At the moment, the area labelled THIRD is entirely dedicated to the 6522. What I want to do is divide the area up, so that different parts of that area select different devices. Then the 6522 will just become one of those devices.
I must revise my address decoding logic. Rather than just a single select line I need a number of them.
The important extra addition here (from the original circuit in part three) is the 74xx138 (I say xx because it could be LS, HC, or other variants) which is a three-to-eight line decoder. It reads three inputs as a binary value, and then selects the line that corresponds to that number.
The elegant part is that to provide the three input lines, we just wire them to three lines of the address bus. The device selected depends on which range (within “THIRD”) we access.
With the above circuit, the address bus pins are now decoded in the following way:
When A15 is low, then we’re accessing the first 32K of address space – that’s all for the RAM. So we can ignore all other address lines in that case.
When both A15 and A14 are high, we’re accessing the final 16K of address space – that’s the OS ROM. We can ignore the other fourteen address lines in this case.
When A15 is high and A14 is low, we’re accessing “THIRD”. In this situation, A8, A9 and A10 come in to play, allowing us to access devices 0 through 7.
What about address lines A11 to A13?
It’s a good question! Wouldn’t it make more sense to use the highest available address lines, so that all the “don’t care” lines are available as register select lines for the devices? That would be more efficient, wouldn’t it?
And the answer is: yes, it would. But in practice, there’s no way I’ll need to use all the “don’t care” lines for register selectors. Most devices only need four at the most. So if I know I’m still wasting quite a bit of address space with this design, then I have more freedom about how I select each device.
The reason I’m using A8, A9 and A10 as the device select lines is that these are the lowest three bits of the second nybble of the address. So it becomes really easy to see which device I’m selecting just by looking at the address (whether in code, or my address display) – it’s the seond digit along!
- &8000 – selects device 0
- &8100 – selects device 1
- &8200 – selects device 2
- … and so on …
The photo above shows my address decoder board, but with a 74HC138 ‘patched-in’ on the tiny breadboard.
When I designed the PCB I deliberately had the /THIRD line go through a jumper, because I had a feeling I’d be evolving on it pretty soon. So where the jumper used to be, there’s a brown wire leaving the board (which becomes the select line for the 74HC138) and the red wire that returns repurposes that line on the backplane from /THIRD to /DEVICE0. Which means that my 6522 circuit responds to the same addresses I coded in my previous example – so my existing code continues to work!
Now I have the provision for more devices in my computer, I can add some more! Stay tuned …