Theory of RAM and ROM modules

A project log for MC68000 Computer

BenchoffBenchoff 01/15/2014 at 11:589 Comments

Although it might make sense to start this project by building a CPU module first, I decided it would make more sense to start with the memory for this system. This serves two purposes: as an explanation of how the 68000's memory-mapped I/O works, and to have a relatively simple circuit built before embarking on the more complex that include the CPU module.

A 68000 memory access primer

As with the 6502, 6800, and 6809, memory access is controlled by the R/W line. Basically, when the R/W line is high, the 68000 reads from the data bus. When the R/W line is low, the 68000 writes to the data bus.

Unlike the older, smaller, 8-bit CPUs mentioned above, the 68000 also has additional control lines to deal with. /UDS and /LDS are the upper and lower data strobe lines. These signals indicate valid data on data lines D0-D7 (for /LDS) and data lines and D8-D15 (for /UDS).

In addition to the data strobe lines, there also exists an address strobe line, /AS. This signal indicates a valid address on the address bus.

Reset Vector Generation

Before designing our memory modules with these signals in mind, it's very important to figure out how this computer is going to boot. All computers require some amount of RAM somewhere in the address space, and at least a few instructions telling CPU what to do on a restart somewhere else. The 6502, for instance, requires an instruction in ROM at $FFFC, and a few bytes of RAM at $0000.

This isn't a problem for the designer of a 6502 computer - just put some RAM at the bottom of the address space, and your RAM at the top.

The 68000 is different. It's reset vector, or the place it looks for instructions on a reset, is at $000000. The 68000 also requires a small amount of RAM at address $000000. Let that sink in. The naive analysis of these two facts means we must store the first instruction in RAM. RAM that will be uninitialized when we boot the computer.

Fortunately, Motorola application notes give us an easy way to get around this. The solution is to deselect the RAM and select the ROM during the first four bus cycles. This can be done with a 74164 binary counter, using the /AS line as the clock input, and making a /ROMSELECT control signal with one of the outputs. This /ROMSELECT or /BOOT signal (I'm using the two interchangeably) will allow CPU to read instructions from the ROM on reset.

ROM circuitry

Above is a fairly broad overview of the ROM board's circuitry. I'm using two 32kB EEPROMs for the ROM, split between high bytes and low bytes. This gives me 64kB of ROM for this computer, more than enough to set up a few things on boot and eventually pull data off a hard drive.

There are basically three main components of the ROM module: an address decoder that enables the ROM, memory control logic that selects which chip is being read, and the ROM chips themselves.

ROM Decoding

According to the memory map I have in my notebook, the 64kB of ROM will be decoded at $500000 through $50FFFF. This means the ROM is selected whenever address lines 22 and 20 are high, and lines 23 and 21 are low. A three-input NAND gate (74ls10) and a few inverters are all that are needed to enable the RAM.

Of course, I'll also need to include the /AS line and the /ROMSELECT line. Easily done.

ROM Memory Control

The ROM memory control is used to toggle the output enable pins on the EEPROMs. The Motorola 68000 user manual has a table going over when valid data should be on the data bus according to the /UDS, /LDS, and R/W lines. Long story short, the above circuit will work just fine for enabling either EEPROM.

RAM Circuitry

Yes, this is much more complex than the ROM module. This is a product of the 68000's huge address space, and my desire to have a ludicrous amount of RAM. Above, you're looking at 4MB of RAM split between eight 512kB SRAM chips. Here's the diagram of the RAM decoding and control logic:

This actually isn't terribly different than the ROM circuitry. There are three basic parts, memory control logic, an address decoder, and the RAM chips themselves.

RAM control logic

Again, surprisingly similar to the ROM control logic. The /UDS, /LDS, and R/W lines control if the CPU is currently reading or writing to D0-D7 or D8-D15. This circuit, a single 74LS32 quad OR gate and a single inverter, takes care of the output enable and write enable of all the RAM chips

RAM decode logic

Here's where things get interesting. The RAM will be decoded into addresses $000000 to $3FFFFF. A little bit of cleverness means there's a one-chip solution (74LS138) to decoding where in our four banks of 1024kBx16bit memory banks the CPU should read and write from.

Also in the address decoder is the ability to disable the RAM when the /BOOT signal is active.

/DTACK generation

Compared to 8-bit microprocessors, the /DTACK signal is a bit odd. It's one of those historical oddities that goes to show how advanced the 68000 was in the early 80s.

The purpose of the /DTACK line is to tell the CPU, "yes, there is valid data on the data bus." The only case where there wouldn't be valid data on the bus is in a case where the CPU is accessing really slow RAM chips or EEPROMs. In this case, the CPU would wait (hence 'wait states') for the data lines and /DTACK to become valid, or throw an exception.

Since I'm using very fast RAM chips and fast enough EEPROM chips, there's no danger of the CPU not getting the data it needs in time. Therefore, the reasonable course of action would be to ground /DTACK and let the CPU pull data off the bus as fast as possible.

There is, however, a problem with this. This computer will also be using 6850 communications chips for the serial ports. The 68000 has control signals used expressly for 6800 peripherals: the E, /VPA, and /VMA lines. Using these control lines means /DTACK must not be asserted, meaning I can't just tie /DTACK to ground. I'll have to generate a /DTACK signal when I access RAM, ROM, and other non-6800 peripherals.

Above is an example of /DTACK generation for the RAM module. If one of the four chip select signals are active, /DTACK is asserted. I also have the circuit for ROM /DTACK generation, but that's lost in a notebook or in an Eagle schematic.

That's just about it for how the RAM and ROM works. As always the schematics and fun stuff are available on this project's git.


DL101 wrote 02/27/2015 at 11:13 point

Is there a way to force the 68000 to use a 8 bit rom?
I know that the 68020 has a bus size selector.

  Are you sure? yes | no

Benchoff wrote 02/28/2015 at 01:39 point

Yeah, use a 68008. That's how most of the 68k builds around the internet solve the problem of hi and low ROMs.

  Are you sure? yes | no

DL101 wrote 02/28/2015 at 16:27 point

Ah, thing is I already have a very nice ceramic gold 68k, with I already built a 68k sbc, but it was built on a prefboard, which is messy. So now I am looking in a more elegant solution, maybe something that would run uclinux. having one rom chip less would save pcb space, and reduce cost, so that is why I am asking.

  Are you sure? yes | no

Benchoff wrote 02/28/2015 at 17:12 point

You might try looking at the M27C160. It's obsolete, and you'll have a hard time finding the part, but it is a 16-bit wide data bus. It does mean a bigger chip, though.

Maybe stack them on a breadboard with the data pins going elsewhere?

  Are you sure? yes | no

DL101 wrote 02/28/2015 at 18:55 point

EPROM, might work, but I hate the half-hour uv erase cycle.
I don't want anything off board, except a peripheral connector, and it should fit on a 10x10 pcb, with rams being on separate modules.
Might just fit, but before I do that, ill finish my other projects, this is only a thought i had.

  Are you sure? yes | no

jachim wrote 03/03/2014 at 22:08 point
I think you might mean "ROM at the top" here...

  Are you sure? yes | no

raven123crow wrote 03/10/2014 at 14:32 point
my thoughts exactly

  Are you sure? yes | no

lennart.lindell wrote 02/18/2014 at 20:59 point
Connect /AS to an active low enable, The same with A23. Then let A22, A21 and A20 go to A2, A1 and A0 on the 74138. Then you have decoded $000000 to $7FFFFF in 8 parts. The /boot is needed on the first RAM only.

  Are you sure? yes | no

Benchoff wrote 02/20/2014 at 22:45 point
Niiice. Good thing I haven't started wrapping the RAM up yet. I'll update my notebook.

  Are you sure? yes | no