For our next design example we will make things a little harder for ourselves. The goal of this example is to allow the Z80 to address 1MB of memory. The Z80 microprocessor can only address up to 64K of memory. Well, at least at any one moment in time, that is.
What we need is an MMU, or Memory Management Unit. Modern processors, such as the Intel 80386/486/etc, all have MMUs built into the CPU chips. The Z80 doesn't have one. Several techniques have been developed over the years to perform this function. Some are probably better than others. My favorite is the one described in some detail earlier. We will implement this MMU in hardware on this example design.
When we are done, we will have an MMU which will map memory in 4K pages. This is an adequate size for our use, It balances page granularity with hardware, and software, complexity. A TTL chip exists that will allow us to achieve this goal in two parts. Look at page 1 of the schematics for this design. You will immediately notice that two 74LS189's have been added in the upper right corner of the page. Note also that the Z80 address lines 12 through 15 have new names. They are called ZA12 to ZA15, and they go directly to the 74LS189's. The 74LS189 is a 16 by 4 register file. It is a TTL device, so it is fast. We will not need to insert any delays in the memory cycle to accommodate the MMU we are building.
The data input pins of the 74LS189's are connected to the Z80's data bus. The MMU is written to by a Z80 OUT (C), A instruction. It is important to note that this is the only form of the output instruction that we can use to write to the MMU. When the Z80 executes the OUT (C), A instruction it places the contents of the BC register pair on the address pins. The contents of the C register will appear on the lower half of the address bus, that is A00 through A07. The contents of the B register will be placed on the upper half of the address bus, that is A08 through A15. We will need to place the address of the MMU register to be written in the upper four bits of the B register. This will then be placed on ZA12 through ZA15, and select the proper register for us.
We could not use the OUT (##), A because the Z80 places the contents of the A register on the upper half of the address bus during the actual I/O instruction. We can't use the OTIR/OTDR instruction because these instructions want to decrement the B register after each execution. This MMU approach was discussed in great detail earlier, but we will review the CPU startup sequence here in order to relate it to the hardware. There are a couple of other subtle differences in this design. Note, also on page 1, that the EPROM uses ZA12 instead of A12. This is because we must be able to execute from the ROM at startup because the MMU comes up with all locations undefined.
On page 2 of the schematics you will see our familiar STARTUP flip-flop. But wait. It is not quite the same as in our previous examples. We need to use I/O instructions to initialize the MMU so we don't dare reset the flip-flop on the first IORQ. Instead we will use something more specific, that can also afford to wait until after the MMU is up; the SIO. The SIO can be initialized anytime after the MMU is initialized. When we do this, the flip-flop will be cleared, and the ROM switched out. We are then running from our DRAM.
You will notice that the DRAM used in this example is a 1MB, 30 pin SIMM. This memory requires two more multiplexed address lines than the 64K designs we have been working with. To accommodate this we have added another 74157 multiplexer, at U9. Our MMU generates 20 address lines, just enough to support 1MB of memory. Therefore, we use them all on the multiplexers. The PAL equations for this design are the same as for example one, except that we need to generate an I/O chip select for the MMU.
Since the SIMM module uses common I/O pins we must implement early write. We will also implement CAS before RAS refresh. This makes our design very clean. Compare page 2 of our schematics with example 3. This is much better.
The rest of the design is identical to our previous examples.
/* Also: CKT4.PDS and compiled JEDEC: CKT4.JED */
; Palasm Design Description ;---------------------------------- Declaration Segment ------------ TITLE SAMPLE Z80 DESIGN # 4 SYSTEM TIMING CONTROLLER PATTERN Z80-1 REVISION A AUTHOR TIM OLMSTEAD COMPANY DATE 09/20/96 CHIP PAL1 PAL16L8 ;---------------------------------- PIN Declarations --------------- PIN 1 MREQ ; INPUT PIN 2 CASIN ; INPUT PIN 3 A07 ; INPUT PIN 4 A06 ; INPUT PIN 5 RD ; INPUT PIN 6 IORQ ; INPUT PIN 7 M1 ; INPUT PIN 8 RFSH ; INPUT PIN 9 WR ; INPUT PIN 10 GND ; INPUT PIN 11 PIN11 ; INPUT PIN 12 CAS COMBINATORIAL ; OUTPUT PIN 13 RAS COMBINATORIAL ; OUTPUT PIN 14 STARTUP ; INPUT PIN 15 WRMAP COMBINATORIAL ; OUTPUT PIN 16 CTC COMBINATORIAL ; OUTPUT PIN 17 SIO COMBINATORIAL ; OUTPUT PIN 18 ROM COMBINATORIAL ; OUTPUT PIN 19 RAMSEL COMBINATORIAL ; OUTPUT PIN 20 VCC ; INPUT ;----------------------------------- Boolean Equation Segment ------ EQUATIONS /RAMSEL = /MREQ * RFSH ; THE WHOLE 64K IS DRAM + /MREQ * /RFSH ; REFRESH /ROM = STARTUP * /MREQ * /RD ; ROM IS ONLY ENABLED DURING STARTUP /RAS = /MREQ * STARTUP * /WR * RFSH ; ONLY DO WRITES DURING STARTUP + /MREQ * /STARTUP * RFSH ; ALL ACCESSES AFTER STARTUP + /MREQ * /RFSH * /CASIN ; REFRESH /CAS = RFSH * /CASIN * /RD * /STARTUP ; NORMAL CAS FOR MEMORY READ AFTER ; STARTUP + RFSH * /CASIN * /WR ; HOLD OFF CAS FOR EARLY WRITES + /RFSH * /MREQ ; CAS GOES LOW EARLY FOR REFRESH /SIO = /IORQ * M1 * /A07 * /A06 ; SIO AT 00H /CTC = /IORQ * M1 * /A07 * A06 ; CTC AT 40H /WRMAP = /IORQ * M1 * A07 * A06 ; MMU AT 0C0H