Author Topic: Z80 memory banking for 128K - MMU design  (Read 3750 times)

0 Members and 1 Guest are viewing this topic.

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Z80 memory banking for 128K - MMU design
« on: November 09, 2017, 03:19:53 AM »
Hi everyone,

Okay, I've been busy learning more assembly and writing CP/M software for my Z80 SBC these past few weeks and now I'm taking a break to finish off a couple of hardware tasks I'd like to complete on it.

I'm having more than just a little trouble getting my head around designing an MMU for my Z80 that will allow it to use a 17-bit (128KB) address space. 

For those that are unaware of my lengthy previous post in these forums regarding Z80 fault finding, I'll just state that my software capability far outstrips my hardware and soldering skills.  My Z80 currently resides on a breadboard, but is otherwise a fully-functioning computer with 64K SRAM, CTC, SIO/2, PIO and an Atmega328 micro-controller providing multiple speeds of system clock (2, 4 and 8 MHz selectable from CP/M 2.2 which runs just fine from the CompactFlash card.)

It has a 128KB SRAM chip, though and I would really like to be able to give the Z80 access to the full 128KB of SRAM goodness.  However, after much digging online and finding precious little regarding MMU designs for the Z80, I am resorting to asking here for a bit of a leg-up on the circuit design.

Here's the design specs (or intended memory map, if you will):



So as you can see, I want to divide the memory space into 4 blocks of 16KB:

Area 0, the base 16KB of memory, will be fixed as this forms the ROM space when the computer first boots up and, when CP/M is running, this area is RAM and houses a lot of important CP/M vectors and the start of the TPA.

Area 1 is the second 16KB of RAM space and, if CP/M isn't running, houses a lot of important information for the ROM like the stack, command buffer etc.

Area 2 is the top 16KB of the TPA in CP/M and free memory - so this is the 16KB bank of RAM I'd like to be able to switch with one of the four 16KB banks in the upper 64KB of the SRAM.

Area 3 is the top 16KB of the 64KB addressable by the Z80 (the bottom half of the 128KB SRAM) and is where CP/M, CBIOS etc reside.

So I'd like to be able to swap in any of four 16KB banks in the upper half of the 128KB SRAM into Areas 0, 1 or 2.

So what have I tried so far?  :-//

Well, aside from hunting out some not very helpful schematics online, like this one https://sites.google.com/site/oldcpusrus/home/simple-mmu-for-the-z80, which confuses rather than helps me (remember I'm not so hot on the electronics side), I came up with the beginnings of an MMU design on the back of a fag packet (or would have been if I smoked):



So this allows me to swap Area 2 for Bank 1 or Bank 2 in the upper 64KB of SRAM.  I think.  BUT I can't work out how to finish the schematic so that ANY other 16KB bank in the upper 64KB can be mapped to Area 2 - at least not without the addition of lots of convoluted circuits and logic chips to force the values of A15 and A14 depending on the output from the 273... but then I don't want to mess with the addressing of normal, non-banked memory space.  |O

So, would anyone be kind enough to give me some explicit guidance on how I need to design the circuit (as simply and with as few chips as possible) so as to expand the address bus to 17 bits and allow me to map any of the 4 banks in the top half of the 128KB SRAM to Area 2 in the lower half of the memory space?

UPDATE: (Edited to update requirements for CP/M 3 compatibility.)

I've been reading through the CP/M 3 system guide (seems I should have done that before I decided the specifications for the MMU  :palm:) and it appears that CP/M 3 wants the bottom three areas (0, 1 and 2) to be switchable, rather than just the one...

So now I'm looking to have three switchable 16KB banks, Areas 0, 1 and 2, that I can switch the banks in the upper 64KB into and out of at will.  I like the idea of being able to map any bank to any area in the memory space, so that's a key requirement for the MMU design now.
« Last Edit: November 09, 2017, 07:47:07 AM by nockieboy »
 

Offline Mjolinor

  • Regular Contributor
  • *
  • Posts: 232
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #1 on: November 09, 2017, 03:33:52 AM »
It has been a long time since I did any messing with Z80s, around 40 years if I had to guess.

At that time I would probably have solved this problem with a UVEPROM that contained a look up table and used the data lines to drive the relevant address lines on the thing I wanted the data from.

I hope that is enough to start your brain because specific would really tax me nowadays.
 

Offline jm_araujo

  • Regular Contributor
  • *
  • Posts: 52
  • Country: pt
Re: Z80 memory banking for 128K - MMU design
« Reply #2 on: November 09, 2017, 04:04:03 AM »
I think you can solve it with a single  74HCT157 - Quad 2-input multiplexer. See attached schematic.

I didn't redesign the parts already in your schematic. "Dn_Latch" are the outputs from the 74hct273 (with an extra D2), "1Y" is the same as yours (area 2 selected).
If other area is selected A16=0, SRAM_A14/A15=CPU_A14/A15

If area 2 is selected, A16=D0, A14=D1, A15=D2 (change as it best suits you, it was made in a rush).

This way you can map any memory area to area 2, so be careful :)

 

Offline bsudbrink

  • Regular Contributor
  • *
  • Posts: 95
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #3 on: November 09, 2017, 04:05:27 AM »
Use something simple like a 7475 latch at a particular I/O address to drive some of the EPROM pins and give you software control over the banking.
 

Online glarsson

  • Regular Contributor
  • *
  • Posts: 151
  • Country: se
Re: Z80 memory banking for 128K - MMU design
« Reply #4 on: November 09, 2017, 05:12:17 AM »
The CP/M system I designed, built and used in the early eighties had a MMU designed using 74170 register file (SRAM). The 7417 is (was?) an odd thing with separate data and address lines for writing and reading. It has two address lines and four data lines (not a large RAM).

The way to build a MMU from it to connect A14 and A15 (on the Z80 side) to the two address lines used for reading and the four data outputs to A14, A15, A16 and A17 (bus side). RE (read enable) is grounded. More 74170 can be used to address even more memory and/or address smaller segments. Note that the 74170 has open collectors on the data outputs and will need pull up resistors. The four data inputs connect to D0, D1, D2 and D3 on the Z80. The two address inputs connect to A0 and A1 on the Z80. The write enable (WE) connect to some decoding logic that decodes the port space and write signals from the Z80.

The 74170 will now appear as four byte sized I/O ports (write only).

After reset the content is unknown so you can not use anything on the bus side until the 74170 has been initialized. I did this by having the boot EPROM on the inside of the MMU. It had incomplete address decoding so it was replicated all over the 64k address space. When the Z80 started running at 0000 it jumped up to the same EPROM at 64k-4k. After initializing the 74170 it then copied itself over to RAM (the write signal went to the bus, the read signal to the EPROM). Then a flip/flop was set and the EPROM was removed from the address space.

I ran CP/M 3.0 (also known as CP/M Plus) on this machine. This version of CP/M supported memory banks. The way I used my MMU was to have 16k at the bottom for CP/M variables and first part of the TPA and 16k at the top for the last part of the TPA. At the top was a very small bios used to switch bank and vector all CP/M calls to a different memory bank. The middle two 16k banks had three alternatives, 32k TPA, 32k disk buffers or 32k CP/M bios and bdos.
The memory was 64 times 6116 CMOS RAM (2k-byte) for a total of 128k. All wire wrapped. The MMU used more than one 74170 to make expansion to 1MB possible, but that never happened. To expensive (both cost of RAM and wire wrapping time).
 

Offline David Hess

  • Super Contributor
  • ***
  • Posts: 5471
  • Country: us
  • DavidH
Re: Z80 memory banking for 128K - MMU design
« Reply #5 on: November 09, 2017, 07:35:27 AM »
One trick I remember is to have separate banking control for reads and writes.  Now banks may be configured to act like ROMs if necessary, ROMs may be copied into overlayed RAM which is then swapped, and copying from the current visible bank to a hidden bank at the same addresses becomes trivial.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #6 on: November 09, 2017, 07:42:59 AM »
Okay, thanks guys - there's some good starters for 10 there.  I've been reading through the CP/M 3 system guide (seems I should have done that before I decided the specifications for the MMU  :palm:) and it appears that CP/M 3 wants the bottom three areas (0, 1 and 2) to be switchable, rather than just the one...

So now I'm looking to have three switchable 16KB banks, Areas 0, 1 and 2, that I can switch the banks in the upper 64KB into and out of at will.  I like the idea of being able to map any bank to any area in the memory space, so that's a key requirement for the MMU design now.

If at all possible, I'd like to do it with discrete logic rather than more RAM or EEPROM chips (seems like overkill?)

I think you can solve it with a single  74HCT157 - Quad 2-input multiplexer. See attached schematic.

I didn't redesign the parts already in your schematic. "Dn_Latch" are the outputs from the 74hct273 (with an extra D2), "1Y" is the same as yours (area 2 selected).
If other area is selected A16=0, SRAM_A14/A15=CPU_A14/A15

If area 2 is selected, A16=D0, A14=D1, A15=D2 (change as it best suits you, it was made in a rush).

This way you can map any memory area to area 2, so be careful :)

That sounds like the ideal solution so far - would it require much alteration to allow mapping to ANY area, not just Area 2?
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #7 on: November 09, 2017, 07:44:31 AM »
Need to get your head around memory management. It can be simple, your computer is doing it now.

Area 0
You now have a bit that is controlled by an z80 out instruction. This bit and Area 0 select enables one of two chips.You have a switch with output enabled by Area 0 select. The switch controls which chip select is enabled.
If you add one more bit then you would have four different states. when combined with Area 0 could select one of four chips by using chip select. Area 0 would enable output of a 139
With three bits, you could select one of eight chips. This would use a 138.
So this is many chips swapped into one area.

Now lets look at many areas of a chip swapped into one area.
If the bit is connected to an address line of a chip, you could switch between two areas of the chip. So the Z80 would access Area 0 and the bit would select one of two blocks of memory on the chip.
If you added one more bit(2), you would get 4 blocks from chip. With three bits you get 8 blocks.

Now if you put both of above together you have a X-Y matrix of block. Some bits select what chip ( row ) and some bits select the block (column).

Now this is all using Area 0 select, but you also have four areas to deal with. You want to use the blocks from one chip in the different areas. You get four layers in the Z direction when you add the area selects.

To have the blocks work with four areas you need four sets of bits to select what block is used in each area. You also need a switch to select what set of bits is used.
A 273 has 8 bits, so you could have two bits for each area. You would need a dual one of four data selector to do this. The output of data selector connects to chip address lines and selects one of four sets of bits on the input.
Now if you add an additional 273 and dual 1 of 4 selector you could have four sets(area) of 4 bits(block). Do some numbers, Four Areas of 16k for Z80 & 16 blocks of 16k for memory(256k).   So you have two 273 and two 153 to do this.
Now ram/rom switch is included, Using this larger address space, Rom is addressed 0-128k and ram is addressed 128k-256k.
With power up resetting the two 273's you have the the first block of Rom in each Area. With two Z80 output instructions you can have any block in any Area.

Now that you have got this far, look at the 74LS670 again. Data sheet states it is a 4 x 4 register file. Four sets of bits with each set four bits wide.
To work with this chip you would use 4 I/O addresses and write just 4 bits. The above using two 273's lets you use just two addresses and write two sets of four bits.
Note that the special thing about the 74LS670 is that it has one set of pins to write to the chip and a second set that is used for read. The write set would be connected to Z80 I/O. The Read set address lines are connected to Z80 A14-A15 giving you four areas. The read data outputs are the expanded address A14-A17 address lines. You should note that on power up the data in the 74LS670 is unknown which will need more chips to correct so that Rom is in place on power up..
 
------
Think of a separate memory card. Rom responds to addresses of 0-128k and Ram responds to addresses 128k-256k.
The A14-A17 address lines are connected to the outputs of the 153's.
The A0-A13 address lines are connected to the Z80.
The other lines are connected to Z80 like normal memory.

The Inputs to 153's are connected to outputs of the 273.
The two select lines(a0-a1) of 153 are connected to Z80 A14-A15
The Strobe lines are tied low.
With two 153's each being dual you have a 4 of 4 data selector.

The two 273's are connected as Z80 output ports and the outputs are the four sets of four bits for input to 153's
The 273's are reset on power on so that you get Rom on power up.

Now the cement.
You want four areas of 16k. This uses two bits to select area. If you only had two bits of data in the four sets, you would have four blocks that you could put in any of the four areas. This is four areas with four blocks. You need more bits in each set to expand. Each extra bit per sett doubles the number of blocks.
If you understand how this works  then you can expand even more. Each 153 adds two more expanded address lines and would need input data.
Note that the data sits at inputs of the 153's so that the upper expanded address lines are delayed by 153's input select time.

This is greater then what you asked for, but in the process uses few general chips and works with power on.

 
 
The following users thanked this post: wilfred

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #8 on: November 09, 2017, 10:15:29 PM »
I think you can solve it with a single  74HCT157 - Quad 2-input multiplexer. See attached schematic.

I didn't redesign the parts already in your schematic. "Dn_Latch" are the outputs from the 74hct273 (with an extra D2), "1Y" is the same as yours (area 2 selected).
If other area is selected A16=0, SRAM_A14/A15=CPU_A14/A15

If area 2 is selected, A16=D0, A14=D1, A15=D2 (change as it best suits you, it was made in a rush).

This way you can map any memory area to area 2, so be careful :)

Would an SN74HCT257N be a suitable replacement for the 74HCT157?  I'm trying to avoid SMD if at all possible as my soldering skills are probably not up to it!
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #9 on: November 09, 2017, 10:20:23 PM »
Need to get your head around memory management. It can be simple, your computer is doing it now....
[SNIP]
This is greater then what you asked for, but in the process uses few general chips and works with power on.

I'm going to have to go away and think about what you've written, C - for quite a while. Maybe even draw some diagrams before I can understand the premise.. there's a lot there!  :o
 

Offline jm_araujo

  • Regular Contributor
  • *
  • Posts: 52
  • Country: pt
Re: Z80 memory banking for 128K - MMU design
« Reply #10 on: November 09, 2017, 10:45:39 PM »
Would an SN74HCT257N be a suitable replacement for the 74HCT157?  I'm trying to avoid SMD if at all possible as my soldering skills are probably not up to it!

In this case it will work the same.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #11 on: November 10, 2017, 07:13:40 AM »
nockieboy

  sorry looks like my cement was not good.
Try making a picture.

Large sheet of paper.
1. On right side make a box an label it memory. Draw a line across this block as half is rom and other half is ram.

2. On left side make a box an label it Z80.

First question
   How many areas will Z80 memory be?
When you have number of Z80 memory areas then you know what kind of switch you need. 
You stated 4 Z80 areas, so you need a 4 throw switch.
3. Draw a 4 throw switch to right of center of drawing.

With 4 Z80 areas you have
 Z90
      A15 - A14                          these are area select lines.
                       A13-A0             these are address in the area & block

Expanded memory
  Ea17-Ea14                             These are the block in expanded memory
                       Ea13-Ea0          These are the address in the block.

Back to your drawing

4.  Now to the left of center need to draw something for block address data.
     From switch side you have four boxes.
    From Z80 you have two boxes that are split
So Two boxes wide & two boxes high with some white space separating the boxes

5. now add some logic lines.
  a.  each box of #4 will be connected to a switch input.
  b. the two horizontal boxes will be written by a Z80 out instruction.
  c. The switch position will be controlled by Z80 A14 & A15
  d. The remaining Z80 addresses are connected to memory box.

On Power up you reset the 273's, so all bits are 0 in #4 boxes.
So
6. In memory box, Rom must be low address range of memory to match the 273 on reset.

So you have the 4 boxes of #4 that the contents of a box is Ea17-Ea14   The extended memory block address for that Z80 area.
The switch is selecting which box of data to use as extended address, the block address based on Z80 area.

After two Z80 out instructions you could have this.

Area   Z80                   extended memory
          A15    A14        Ea17    Ea16   Ea15  Ea14
0           0       0             0         0          0        0 
1           0       1             0         0          0        1
2           1        0            1         0          0        0
3           1        1            1         0          0        1

Note that you are using two 273 to store the above data, one out instruction sets data for two areas.

The data in above table states
Z80 area 0  0-16k     = expanded memory block 0 = 0-16k          = rom 0-16k
Z80 area 1  16k-32k  = expanded memory block 1  = 16k-32k     = rom 16k-32k
Z80 area 2  32k-48k = expanded memory block 8  = 128k- 144k = ram 0-16k
Z80 area 3  28k-64k = expanded memory block 9  = 144k--160k = ram 16k-32k

From the Z80 you have 32k of rom starting ar address 0 & followed by 32k of ram
This is the same as if you just had two 32k memory chips connected to Z80.
To get to this state the Z80 did two Z80 Out instructions with the instructions in 0-16k if rom

Org   0 H
; do some initial boot stuff

; then set up memory
  out 273-0, 10h    ; set area 1 bits to block 1   set area 0 bits to block 0
  out 273-1, 98h    ; set area 3 bits to block  9  set area 2 bits to block 8
: now you can set the SP  and continue booting

===============

The switch in the drawing is letting you use two bits of Z80 to get 4 bits to be used as the high bits of the extended address.

======
Things to look at
The switch is doing the decoding of the Z80 area.

  Say you wanted
    0-16k to be rom always at same rom address
   48k-64k to be ram always at the same ram address.
  And want to switch the center two 16k blocks.
You would need memory chips for the two fixed areas & more memory chips for the switched memory. You could use a two way switch in this case.

If you want the fixed rom or ram to come from the memory chips in the switched memory chip area, you need to add at least one more switch position to get this to happen.
Computers work in binary so a 3 position switch is hard to find, you would end up using a 4 throw switch. You could then strap the inputs of the 4 throw switch so that it gives the fixed address to get the above two fixed areas. And data at the other two switch inputs to select wanted block for that area.
By adding just one 273 chip you have data for  four switched areas. This is what you have in drawing.

If you look at the boxes that hold the expanded address, you should see that a few bits can make a huge difference. Two more bits would let you have a 1M expanded address range.

==========
 74LS670
  As stated in last post, you would have a power up problem using this chip. There is a pin on this chip that will make outputs go tri-state. You could control this pin by using one bit of a 273 that was cleared on power up.
To get this to work you would need pull-up resistors on the outputs of the 74LS670 & need to put power up boot code in the highest block of memory.
Ram would be address in 0-128k, Rom 128k -256k.
The highest block of 16k would then be rom and you put boot code in this block.
At power up Z80 would be running block F code with Z80 using addresses in  0-16k.
With Z80 now running the first steps would be to write good data in the extended address blocks stored in the 74LS670 and then enable output of the 74LS670 by writing to 273

Look at drawing again
When you use 74LS670
Rom and Ram areas are wwapped.
The boxes that store extended address are now four tall and use four Z80 output instructions.
The 74LS670 contains the switch and the data boxes.

Using two 74LS670 would let you have a 4M expanded address range by using 4 output ports. You are probably thinking what would I use it for.
One use would be to use memory that is shared or used by a different CPU.

So memory management is simple

You have something between the CPU and Memory that changes addresses that the CPU can control.

If something does not make sense it could be an error in above.

 
 
The following users thanked this post: wilfred

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #12 on: November 10, 2017, 09:19:38 AM »
Yeah, I'm going to have to go away and think long and hard about what you've written, C - I'm finding it a little hard to follow.  ???

Here's what I've drawn up so far - it's more of a serious sketch of the original hand-drawn plans in my first post, but this one includes a slight improvement in terms of using a 74HCT257, thanks to jm_araujo's suggestion.



The problem with this design is that it just answers my original question - i.e. making area 2 switchable with any bank in the upper 64KB of RAM.  What I need to be able to do, having looked at the CP/M 3 System Guide, is to make areas 0, 1 and 2 switchable.  This adds a layer of complexity that is far beyond my simple electronics knowledge and understanding, unfortunately.
 

Online glarsson

  • Regular Contributor
  • *
  • Posts: 151
  • Country: se
Re: Z80 memory banking for 128K - MMU design
« Reply #13 on: November 10, 2017, 09:29:10 AM »
What I need to be able to do, having looked at the CP/M 3 System Guide, is to make areas 0, 1 and 2 switchable.  This adds a layer of complexity that is far beyond my simple electronics knowledge and understanding, unfortunately.
Using a 74140 or 74LS670 allows you to map any memory segment (e.g. 16k) to any e.g. 16k as seen by the Z80.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #14 on: November 10, 2017, 02:16:31 PM »
Look at your last design.

You have more bits in the 273 & one more 1 of 2 switches.
This one bit lets you have A17.
When A17 = 0 rom is selected.
When A17 = 1 ram is selected.
You can get this to happen just by proper connection to rom & ram chips.
You now have 8 banks you can swap in to area 2, 4 ram & 4 rom.
This change is a step to removing all the other chips used to swap rom for ram.

Your switch is a 2 throw switch & is selecting normal Z80 or Banked, but banked is only used for area 2 which needs extra logic to select.

You can remove the logic that selects area 2 by using a 4 throw switch!
Two 153 would let you do this. A 153 is a dual 1 of four switch.
By connecting Z80 A14 & A15 to the 153's A & B inputs, the switch it's self will decode the area removing need for area2 select. For now just strap other inputs to proper levels for the fixed addresses like you have with the 257.

Now if you look at 273 you have 4 bits not used. If you used these 4 bits to select the bank for area 0 you could remove all the other logic that selects rom/ram for system.
Area 0 would point to 0-16k on power up and by writing the 4 bits can point to any block of ram or rom.

This leaves 8 inputs to the 153 strapped to a level. By adding one 273 you have bits needed to change these pins and all areas can be banked as needed.

So two 273's and two 153's give you four areas that are bank selectable & you get to remove current logic that selects rom or ram swap. 

You should note that CS for the rom & ram chips selects chip active or disabled/sleep.
If A17 & Z80 MREQ is used for Chip select then Z80 RD & WR can be directly connected to these chips.

Need to look at big picture when thinking about a change.
You locked into changing only area 2 and not looking at total system and a change that would get a better result.




 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #15 on: November 10, 2017, 10:18:49 PM »
Look at your last design.

You have more bits in the 273 & one more 1 of 2 switches.
This one bit lets you have A17.
When A17 = 0 rom is selected.
When A17 = 1 ram is selected.
You can get this to happen just by proper connection to rom & ram chips.
You now have 8 banks you can swap in to area 2, 4 ram & 4 rom.
This change is a step to removing all the other chips used to swap rom for ram.

Oh yes, I like your thinking, C. :-+   It would be great to improve on Grant Searle's original ROM/RAM switching design with a reversible system.  By default, his system allows you to switch the ROM 'off' when loading CP/M, but there's no way to switch it back in without doing a cold reset of the entire system.  Being able to switch in any bank of the 128KB ROM would be nice too...

Your switch is a 2 throw switch & is selecting normal Z80 or Banked, but banked is only used for area 2 which needs extra logic to select.

Yes, well the whole Area 2 thing was just my initial thoughts on MMU design, partly because it seemed simple and a good idea at the time, and partly because I was unaware how CP/M 3 likes to have the whole bottom three areas switchable!  I've updated the original post and memory map accordingly.

You can remove the logic that selects area 2 by using a 4 throw switch!
Two 153 would let you do this. A 153 is a dual 1 of four switch.
By connecting Z80 A14 & A15 to the 153's A & B inputs, the switch it's self will decode the area removing need for area2 select. For now just strap other inputs to proper levels for the fixed addresses like you have with the 257.

I like the sound of this. :-+  Will have to look at the 153 and spend some time thinking about what you've said here to make sure I understand how it fits together.

Now if you look at 273 you have 4 bits not used. If you used these 4 bits to select the bank for area 0 you could remove all the other logic that selects rom/ram for system.
Area 0 would point to 0-16k on power up and by writing the 4 bits can point to any block of ram or rom.

This is going to require some :-/O on the breadboard (or at least de-wiring of logic chips for the existing RAM/ROM select circuit), but it sounds like a much more flexible and powerful system. ;D

This leaves 8 inputs to the 153 strapped to a level. By adding one 273 you have bits needed to change these pins and all areas can be banked as needed.

So two 273's and two 153's give you four areas that are bank selectable & you get to remove current logic that selects rom or ram swap. 

You should note that CS for the rom & ram chips selects chip active or disabled/sleep.
If A17 & Z80 MREQ is used for Chip select then Z80 RD & WR can be directly connected to these chips.

Okay, I think I already have a couple of 273's knocking about.  Could I use 74HCT253's in place of the 153's?  I'm dippy about DIPs and want to stay away from SMD for as long as possible - plus the adapters are an added expense when prototyping on breadboard and I'm as likely to solder an SMD to my fingers as I am to the board.  ::)

Need to look at big picture when thinking about a change.
You locked into changing only area 2 and not looking at total system and a change that would get a better result.

Consider myself told off! ;)  Seriously though, thanks for that C - I feel I actually have the outlines of a plan now.  I'm going to spend some time this weekend (hopefully) converting what you've written into a schematic that I'll post ASAP for feedback.  :-+
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #16 on: November 11, 2017, 01:26:34 AM »
Is this going along the right lines, C?  I'm not sure this is even right, but going by your previous comments this as close as I can get.  Not sure what to do with the Y1/Y2 outputs of the 253's, though - do they go to A15/A16 on the RAM/ROM?  How do I select between RAM/ROM with this configuration?

 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #17 on: November 11, 2017, 01:43:22 AM »
Just think of what you have

A 4 throw switch

so the switch is area decode and you use two chips the get the expanded address buss width.

the two latches are
the memory for the MMU, The storage of what bank in extended address to use for an area

so put bank decoder under area decoder in your drawing as both are area

label four outputs of these as expanded address or extended address

Your data bus  Area & bank
these inputs are Z80 I/O write to selected address
you are writing two areas extended address data (bank) with one output.

ADDED

The output of Switch is A14, A15,A16,A17
As they are not the same as direct Z80 it is a good idea to change the label

EA14-EA17

Yes yes switch outputs go direct to memory are address lines.

The big difference is that you have the ability to change the address mapping
&
The switch takes time to switch so these higher address lines change slower, need to check timing as this can effect memory read/write times
« Last Edit: November 11, 2017, 01:51:39 AM by C »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #18 on: November 11, 2017, 05:24:31 AM »
You should note that all my posts here are same result.
Two 273's and two dual 1 of 4 switches or mux.
I just modified your drawing step by step.

Speed of the switches is important. Faster gives you more time for memory.

Normal Z80 Memory connection.

Most memory chips do nothing when CS is inactive.
Most expect address inputs to be stable when CS goes active.
With CS inactive changes on RD and WR are not used or looked at.
Your memory works like this.

I say most as there are many ways to connect memory and types of memory

So Normal Z80 has RD & WR directly connected to memory. The selected chip will respond to memory cycle.

Memory CS is a combination of Address Valid, which memory chip is to respond & Z80 MREQ

The 138 is build just for this as you can connect one of the enables to Z80 MREQ and if you look at inside logic of chip, some of the enables just turn on the outputs of the chip. This hides all the random states as the address line inputs are changing.
MREQ then will enable output at correct time, removes chip output glitches.

So my good design practice it to use proper chips in correct place and really check the timing & time delays to try to prevent glitches that are very hard to find.

So You have two 128k chips and need a decoder to select which chip based on EA17 & Z80 MREQ

Pick a decoder chip and use it. You have many choices 138, 139 and many others.

Now look at your memory timing.
The data in the 273 is static, not changing on a memory cycle.
The address buss from Z80 starts changing.
The Switch takes time to switch inputs and get proper static output so this adds a delay.
Then Z80 MREQ happens and gets sent to decoder chips.
The decoder chip takes time so you have a delay here also.
The output of decoder chips start the time clock on the memory CS time.

So is address stable when CS of memory chip goes active?
Now keep in mind that for Z80 address starts changing on one clock edge and MREQ is a different clock edge.
It is not hard to add some delay to MREQ.



Look at removing Grant's logic.


Having a Cold reset & Warm reset is a great thing.

U8 is not common in most designs I have seen
  With most designs I have seen MREQ and IORQ are  output enables of address decoder chips.

Looking at the SIO the CE pin would go low(active) when proper address is valid and stable and IORQ is active. U5 is missing a IORQ input to enable pins to make this case.

You could do some tests to verify that the following changes work step by step with the result of removing grant's logic.

1. On U5 connect pin 5 (E0) to IORQ instead of A7
     Test computer all should work fine. You should be able to send/receive via SIO and you should be able to read and write to CF Card with out errors.

2. With change 1 in place, you should be able to move connections to J1 piins 4 & 5 to connect to the Z80 RD & WR in place of U8c & U8D.
    Run tests of #1 again and you should see no problems.

Starting change to add new Memory mapper.

3 You will add a decoder chip and connect it to an un-used output of U5. You will use this I/o address range to control the MMU. When MMU is working properly you can then remove grant's ram/rom logic.
  Add a 138 or 139 chip. The U5 un-used output can be connected to an enable pin or an address input of decoder. One of the enables will be Z80 WR. Connect A0 & if possible A1,A2 to this chip.
You now have outputs that are IO write that can be connected to 273 chips.

4. A quick test  of what you have to this point.
connect one 273 to #3 and use a output of 273 to change input of U8D pin 12.
  heck/verify  that a 0 output of 273 selects ROM chip.
Add software in Z80 to change the bit in 273. leave old software for grant's in place.
    Run #1 tests.  Should work for grant's logic or 273 output.


Keep in mind that a MMU goes between CPU and Memory.
This MMU uses a few I/O writes to control it's operation.
You might want to put this circuit on a separate breadboard.

A step by step change for memory is harder to do. You need all four chips connected properly with some changes to memory chip selects & software.
 
5. with U6D connected to grant's logic, build MMU circuit.
   Do NOT connect switch outputs yet.
   You will need to write software for MMU. Do this by adding software leaving grant's software.
   On power up you will have all ROM so use software to make MMU select
   0-16k rom for area 0 and ram for other areas.
   Where software changes to all ram, add code to change MMU (the 273 data) for all ram. Leave grant's software in place.
   Check proper data is written to the two 273's
   Will need to use scope to verify that Switch outputs is working.


6. Now that you have this much working and tested as much as you can, change memory selects so that MREQ is used to control CS of memory chips and EA17 is also used.  Rom = 0-128l Ram = 129k-256k when looking at the expanded address.
If you need logic to do this I would use a decoder chip.
Connect MMU outputs to memory.

7. Test it.
    with proper software for MMU you should see no change from what you have now.

8. Here you can remove Grant's logic that is not used.

You should note that for CP/M3 & TurboDos you can start the computer running CP/M2 and run a command to change to new system.
This makes testing the software changes needed for new OS easer.
   


You can use the 74ls670 if you want to.
The cmos versions of this chip are very slow, you need LS or faster.
If you order this chip 74LS670, I would get 2 or more.
You will also need pull-up resistors for outputs of chip.

The basics are the same as using 4 chip MMU
The 74ls670 will use 4 Z80 out addresses instead of 2.
Rom/Ram is swapped in extended memory
One step that you might have trouble with is loading boot code into the highest 16k block of Ram.

Something you might want to think about. The Z80 can program the ROM you are using.
 

Offline jaycee

  • Regular Contributor
  • *
  • Posts: 109
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #19 on: November 11, 2017, 07:19:07 AM »
Worth looking at the design of the ZX Spectrum 128, which banks memory in the top page of the Z80's address range. It's quite a simple mechanism.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #20 on: November 11, 2017, 08:49:34 AM »
Worth looking at the design of the ZX Spectrum 128, which banks memory in the top page of the Z80's address range. It's quite a simple mechanism.

Yeah, that's no good for me as I want to make my computer compatible with CP/M 3, which requires the bottom two thirds of RAM to be switchable.  I noticed some interesting stuff going off with the AY sound chip in the 128's schematic though - looks like they control the keyboard and RS232 through the AY's IO ports..

Looking at the SIO the CE pin would go low(active) when proper address is valid and stable and IORQ is active. U5 is missing a IORQ input to enable pins to make this case.

Yes, Grant's design is missing the IORQ input to U5, but I've added it to mine so the 138 only responds to proper IO requests.
 

Offline Jr460

  • Regular Contributor
  • *
  • Posts: 57
Re: Z80 memory banking for 128K - MMU design
« Reply #21 on: November 11, 2017, 09:33:54 AM »
I didn't read all the post in this thread in detail, so maybe I'm stating something already discussed, sorry.

Many years ago, before CP/M 3.0, when 2.2 was king, I worked on a MP/M system.  It was multi-user CP/M and if you wanted it work well you needed bank switched memory.  Like 3.0 the top part of memory was not switched.

(If think about it this is way most modern virtual memory OSes work.  System space for the OS and devices is the top half of the virtual address space and process private is the lower half.)

The system I worked on was S100 buss based and the memory cards were 48K each and had a dip switch that set the IO port number that the card would listen to to turn it on or off.  It was up to MP/M to keep track and only have one card enabled at a time.  One card in the system had a full 64K, and the lower 48 could be disabled again with an OUT command.

Maybe look for old schematics of those S100 boards and see what they did.  At least you know CP/M 3.0 will work with with that method of memory management.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #22 on: November 12, 2017, 03:01:03 AM »
Okay, this is where I'm at with the schematic based on C's discussion above (ignore the labelling for ~AREA and ~BANK - they're just IO select lines from the '138.)



I'm flying blind a little bit as I don't fully understand how this will work - or even if it WILL work - I've just thrown it all together based on C's posts.  You don't want to hear excuses, but I've had a busy day with the family and now have a splitting headache, so I'm struggling to work out how and if this circuit works at switch-on.

At power-on, the default state should be:  ROM - 0000h-3FFFh, RAM - 4000h-FFFFh.  The ROM should be able to be switched-out with an IO call so that the entire 64KB memory space is RAM, for CP/M to run.  This is handled by EA17 in the schematic.

Now bearing in mind I don't really know how this is supposed to work - aren't I going to have to set a default value in the latches to ensure the above default ROM/RAM memory state is enforced?

If no banking is enabled, how does A14 and A15 get passed through to the RAM/ROM?  Do I need to connect A14/A15 to 1C0/2C0 on the 253 that outputs EA14 and EA15?  This circuit just feels incomplete...  :-//

I didn't read all the post in this thread in detail, so maybe I'm stating something already discussed, sorry.

No need to apologise! Welcome to the discussion, Jr460!  :D

The system I worked on was S100 buss based and the memory cards were 48K each and had a dip switch that set the IO port number that the card would listen to to turn it on or off.  It was up to MP/M to keep track and only have one card enabled at a time.  One card in the system had a full 64K, and the lower 48 could be disabled again with an OUT command.

Maybe look for old schematics of those S100 boards and see what they did.  At least you know CP/M 3.0 will work with with that method of memory management.

I'll have a hunt for S100-related schematics then - there seems to be a couple of sites relating to S100 computers that I've come across previously.  I feel I'm getting somewhere with my current design, though and if I can complete it, it'll be extremely versatile as it will allow me to map ANY 16KB bank of memory space to ANY 16KB bank in physical RAM or ROM.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #23 on: November 12, 2017, 04:08:50 AM »
At powerup, after /RESET is released, both latches will have '0' on all outputs.  A14 and A15 will therefore be ignored and the low 16K of the ROM will be mapped to the whole address space, repeating four times.  By writing to the latches you can map any bank of RAM or ROM at any 16K page in the address space.  However you would do well to rearrange the input lines to the multiplexors so EA14-EA17 for a single page are controlled by four bits on the same latch, otherwise it will be difficult to switch mappings without smashing the mapping for the page that is currently executing.

However this seems over-complex.  Personally, I'd use a 74HC670 4x4 addressable register file to expand the addressing.  It does *NEARLY* everything the above circuit does in one chip.   That would give you a separate port write to control each page, with two bits in the data selecting the page and four bits selecting the bank, but would need the addition of a flipflop driving its /RE pin (that controls its output tristate capability) set by /Reset and cleared by an unused data bit decoded at the port address+ 10K pullup or pulldown resistors to set the default powerup mapping.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #24 on: November 12, 2017, 07:06:55 AM »
By writing to the latches you can map any bank of RAM or ROM at any 16K page in the address space.  However you would do well to rearrange the input lines to the multiplexors so EA14-EA17 for a single page are controlled by four bits on the same latch, otherwise it will be difficult to switch mappings without smashing the mapping for the page that is currently executing.

Ah, right - how should I rearrange the multiplexer input lines to achieve that?

However this seems over-complex.  Personally, I'd use a 74HC670 4x4 addressable register file to expand the addressing.  It does *NEARLY* everything the above circuit does in one chip.   That would give you a separate port write to control each page, with two bits in the data selecting the page and four bits selecting the bank, but would need the addition of a flipflop driving its /RE pin (that controls its output tristate capability) set by /Reset and cleared by an unused data bit decoded at the port address+ 10K pullup or pulldown resistors to set the default powerup mapping.

Okay, I'm nearly persuaded - I'll see if I can get a basic understanding of how it works from the datasheet and throw a schematic together to see if I can pull this off. 
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #25 on: November 12, 2017, 07:21:57 AM »
You are getting there keep up good work.

An MMU enables lining to CPU about where the memory data actually is.
Remember that it takes time to do this. Here the 153 is delaying address data from A15,A14 to EA15,EA14
The 153 must select the input pin and the data on that pin then needs to get to output of 153.

An example of this MMU in use.
Your 128k rom has 8 blocks of 16k.
One block needs to be the Z80 power up boot code.
This boot code could ask you to pick 1 thing from the 7 other blocks.
Block 1   your system monitor program
Block 2  Grant's basic
block 3   microsoft's basic
...
Block 7 something.
All these different programs could be assembled to ORG 0H
The power up boot code when it gets an answer,
Sets area 0 to the proper block
jumps to address 0H
If you selected 1 then you are running the monitor.
selecting 2 gives you grant's basic.

This is just very simple use of this MMU.

=====

As  Ian.M pointed out and in my posts above

The Area bits should be together in one 273.
Each 273 will hold two areas.
So two bits of 273 area go to one 153 and the other two go to other 153.

The data stored in the 273 for an area is EA17-EA14 used to address memory.
The Switches (the 153) selects 1 of 4 sets of data based on Z80 A15-A14.
So if both Z80 A15,A14 are low, The switches select area 0 data The expanded address EA17-EA14 which then goes to your memory chips.

Your two 273 chips make up a 2 x 8 bit memory chip.
The Reset/clear inputs lets you force contents of the 2 x 8 memory chip to all 0.
Being able to set memory data to 0 like this is not normal for memory. You Ram memory chip when power is connected will have random data.

Now the 153 switches is using this 2 x 8 memory as if it is a 4 x 4 memory chip.

Think of your current ram chip
It has one set of data pins. You use these pins for both read & write.
The two 273's is like a  2 x 8 memory chip. It has data pins for Write & a set of data pins for read.
The 273 based memory has a data port for write and a data port for read.

You are using a 1 of 4 switch on the output of the 273 memory.
Your current ram chip has a built in 1 of 128k switch to select data.
A normal memory chip stores data, your 273's stores data.
A normal memory chip has a data selector,  the 153's are data selectors.
A normal memory chip has no reset input, the 273's does.
Most normal memory chips have one data port, the 273's + 153's have two data ports.

Now look at the 74LS670.
It is a 4 X 4 memory chip.
It has a data & address port for writing data.
it has a data & address port for reading data.
It has NO reset input.
It has a tri-state output for read data port.

This chip does all most the same thing as the two 273's & two 153's
Would use 4 outputs addresses of 4 bits.
It is a RAM memory, So you have random un-known data in the 74LS670 at power up.
To get valid data on output pins at power up,
You connect pull-up resistors to the Read data port that is connected to memory, when you enable tri-state mode the resistors will supply a 1 to memory address line.
When the 74LS670 read port is tr-stated your ram and rom chips will see an address of EA17-EA14 all being 1.
By tri-stating read port at power up, The Z80 when reset will ask for address 0h, The memory will respond with data fromEA17-EA14 = 1 + Z80 A13-A0 = 0.
The Z80 is reading the top 16k of memory but thinks it is the first 16k of Z80 memory.

Your Z80 boot program is running and can now put initial data into the 74LS670. When that is done the Z80 can then turn-off the 74LS670 tri-state and start using the data in the 74LS670 for  EA17-EA14.

So
An MMU is put between the CPU & Memory.
It allows lining to CPU about where the memory data is in the actual memory.
The CPU has a way to change the LIE

The computer you are using to look at this will probably have an MMU.
The OS can use the MMU to keep one user of program from messing with another user or program.
If a user or program can not access something then it can NOT make changes.
A computer can run more programs or data then will fit in memory, if it can store the memory contents for a while in mass storage, This is called Virtual memory.

Your mmu is using 16k blocks & has 4 areas.
Some systems use much smaller area blocks. One system I worked with used 512 byte blocks.
To change your MMU you may need to change 4 sets of 4 bits.
Using the same total memory(256k) and same 64k CPU memory the MMU using 512bytes could need to change 128 sets of 10 bits.

If you changed the MMU to use 4 sets of 8 bits then the total memory would increase to 4m.
This would be two sets of 4 chips or 2 74LS670's

Keep in mind what you might want to do in the future.
The 512k dip memory I found was in a 32 pin package.
The Z80 being able to access a lot of memory space is a powerful thing.
Memory does not have to be memory.
Some CPU's have I/O in memory space.
The extra memory space could be connected to other processors.

 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #26 on: November 12, 2017, 08:23:19 AM »

Little steps trying to use what you know.

You are using grant's logic to do Ram/Rom

Remove some of this and use a 273

U7 C & D is a FF
A 273 is 8 FF with a reset/clear input

To use a 273 you need a signal to drive the clock input.
You want to clock this input with a Z80 out instruction.
You need IORQ & WR & a valid write address.

With IORQ connected to U5 you have part of this.
You can use an additional 138 or 139 to get what is missing.
Lets use a 138 as it is easer to understand.

The 138 has three enable inputs.
One needs to be connected to U5
One needs to be connected to WR
A0 connects to A input
A1 to B input
A2 to C input
You how have 8 outputs that are Z80 I/O write to a address.
You can connect up to 8 273's
You can connect other types of chips to these outputs.
So you can connect one 273 and get the reset on power up of grants logic needs by using one output of the 273.
A zero on output of 273 needs to select ROM.

To get the 74LS670 to work
You need one output from the 273 connected so that a 0 makes the 74LS670 output goes tri-state.
OR
  You keep using grant's logic and have ROMDisabled connected to 74LS670 tri-state input pin 11.

Wa & Wb connect to Z80 A0 & A1

Gw ineeds to be Z80 out for a range of 4 addresses.
U5 is I/O for a range of 8. Need to add WR to this
With a 138 you would not connect A0 & A1 so that each output of 138 gives a 4 address ramge.


With 139 you only have one enable.
Connect WR to one half's enable.
Need to use one of the address input pins to connect to U5.
By connecting A0 to other address input pin
You get Y0 and Y1 as a valid Z80 output select.
Y2 & Y3 are no connects.
You can connect two 273's to the valid outputs.
When connected to U6
even address writes to 1 273, Odd address writes to other 273


for 74LS670 with 139
You connect A2 to address input
You get four outputs that are a range of 4 output addresses.

The 139 is dual so you could wire it up and connect
Two 273's
&
 Up to Four things that need a 4 address range like the 74LS670
You would need different outputs of U5 for each 139 half

With this you can co I/O write to 4 chip MMU or 74LS670 based MMU

 No other logic is needed for 4 chip MMU or 74LS670


Note my quick look at data sheets for 74HC670 & 74LS670 suggests you want the 74LS670 for the speed.

Parts count

4 chip MMU
1 138 or 139
2 273
2 153

74LS670 MMU
1 139
1 273
1 or more 74LS670
Pull-UP resistors for outputs of 74LS670's
A resistor back would work great.

 



 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #27 on: November 12, 2017, 08:39:22 AM »
Okay, preliminary schematic for an MMU using the 670 chip:



I'm a bit lost with this one - one minute I'm getting my head around using 273's and 253's, now I'm looking at a 670 and wondering how I connect it up...  :o :-//

Okay, so I know I have to add pull-up / pull-down resistors as appropriate to set initial startup values when the 670 is tri-stated during power-up - I need the bottom 16K of the ROM to be available to the Z80 in the bottom 16K of memory space on startup (0000h-3FFFh) - so I have a couple of questions regarding this circuit:

1) How do I finish connecting it up to the address bus / control line/s.  Do A14/A15 go to both the read and write address inputs on the 670?

2) I assume the IO select lines go to ~WE and ~RE?

3) Have I connected up the Qn outputs correctly to the address lines on the RAM/ROM?

4) The pull-up/pull-down resistors go in the data lines (D1-D4)?

5) Where does the flip-flop go?

You are getting there keep up good work.

Thanks C - though it's causing me some headaches now!  |O

Now look at the 74LS670.
It is a 4 X 4 memory chip.
It has a data & address port for writing data.
it has a data & address port for reading data.
It has NO reset input.
It has a tri-state output for read data port.

This chip does all most the same thing as the two 273's & two 153's

Yes and because of that (and my keep-it-simple mantra) I think I'm going to develop the 670 idea from here.  I just have a really poor understanding of how it works (or how to get it to work.)

To get valid data on output pins at power up,
You connect pull-up resistors to the Read data port that is connected to memory, when you enable tri-state mode the resistors will supply a 1 to memory address line.

Erm.. where?  Are you talking about D1-D3 on the schematic?

If you changed the MMU to use 4 sets of 8 bits then the total memory would increase to 4m.
This would be two sets of 4 chips or 2 74LS670's

Keep in mind what you might want to do in the future.
The 512k dip memory I found was in a 32 pin package.
The Z80 being able to access a lot of memory space is a powerful thing.
Memory does not have to be memory.
Some CPU's have I/O in memory space.
The extra memory space could be connected to other processors.

At the moment I'll be ecstatic if I can just get an MMU working with the 128KB I've got in the SRAM and ROM!  I'm not likely to want to expand the memory further - at least not for the foreseeable future and if I do, I can presumably add another 670 without major upheaval.

I understand the concept of an MMU, the difference between memory space and physical memory etc, I'm just struggling at the moment with the specific technical details of how the 670 works to give the Z80 extra address lines.  Ian.M mentioned the 670 would also require a flip-flop - I do have a 74HCT74, would that be suitable?  Where and how would I need to wire it into the MMU circuit above?

Sorry about all the questions - I'm happy to work my way towards designing this MMU myself, but my understanding of the chips we're talking about (and some of the concepts) is virtually non-existent.  ???
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #28 on: November 12, 2017, 09:42:40 AM »
Now connect  RA0 to Z80 A14 and RA1 to A15.  Connect WA0 to Z80 D4 and WA1 to D5.   Connect /RE to flipflop Q, flipflop D to D7 and flipflop /SET to Z80 /Reset.   Drive '670 /WE and flipflop CLK in parallel from your port address decode logic which should include Z80 /WR.

Now what happens depends on the byte you write to the single control port:

 B7  B6 B5  B4   B3   B2   B1   B0

Boot -- S15 S14 EA17 EA16 EA15 EA14


The MMU effectively matches S14-S15 against Z80 A14-A15 to give you four pages (each a 16K block of Z80 address space). Your ROM extends from EAddr 0x00000 to 0x1FFFF, and RAM from 0X20000 to 0x3FFFF.  You can map any of the four pages to any bank (16K block of RAM or ROM), so to set up a usable memory map, in BOOT mode, with the '690 outputs disabled and EA17-EA14 set by the pullups/pulldowns:
Code: [Select]
   LD B, high(PORT) ; assuming full IO address decoding
   LD C, low(PORT)
   LD A, $80 ; High bit set to stay in BOOT mode
   OUT (C),A ; set page 0 to bank 0 - the first 16K block of ROM.
   LD A, $99
   OUT (C),A ; set  page 1 to bank 9 - the second 16K block of RAM
   LD A, $AA
   OUT (C),A ; set  page 2 to bank 10 - the third 16K block of RAM
   LD A, $3B ; High bit clear to leave BOOT mode
   OUT (C),A ; set  page 3 to bank 11 - the fourth 16K block of RAM
Once execution is transferred to RAM,  you can remap page 0 to RAM as well. Because you want to keep the '690 enabled keep bit 7 clear:
Code: [Select]
   LD B, high(PORT) ; assuming full IO address decoding
   LD C, low(PORT)
   LD A, $08
   OUT (C),A ; set page 0 to bank 8 - the first 16K block of  RAM
« Last Edit: November 12, 2017, 09:46:46 AM by Ian.M »
 
The following users thanked this post: nockieboy

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #29 on: November 12, 2017, 10:08:33 AM »
First a good rule for TTL logic
TTL uses higher current to make a logic 0 then logic 1
Good idea to use Pull-Up resistors for TTL
Using Pull-UP resistors requires boot rom code to be at highest address block.

ian.M is putting all MMU control on one I/O output port.
Saves I/O ports at some possible cost of slower software to control MMU

My setup uses 4 I/O output ports for 74LS670 and one output port for boot.
One for Boot where only 1 bit is used leaving you 7 bits you can use.
4 addresses that you only write B3 to B0 from
 B7  B6 B5  B4   B3   B2   B1   B0
  X     X  X    X  EA17 EA16 EA15 EA14

If you add one more 74LS670 to get 4M range this becomes
B7      B6      B5      B4       B3      B2      B1      B0
EA21  EA20  EA19  EA18  EA17  EA16  EA15  EA14

With pull up resistors connected to outputs of 74LS670, just put the power up boot program in the highest 16k block of ram and have ram at top of memory.
When you disconnect A14 & A15
0000h-3FFFh the Z80 is asking for becomes
??00 0000 & ??11 1111 for high byte of address
The 74LS670 4 outputs are pulled to 1
1111 from 74ls670 and 00 0000 from Z80 to
1111 from 74ls670 and 11 1111 from Z80
This gives
3C000-3FFF range in expanded memory the highest 16 k block

You need the Z80 to see 0-16k as boot program. with the outputs of 74LS670 this is the high 16k of memory.

1.  A14/A15 go to the read data port address lines Ra & Rb

2. A0 A1 go to Wa Wb with the D1-D4 connected to Z80 data lines
   Gw is connected to Z80 output write for a range of 4 addresses.

3. Yes these are the highest address lines for ROM/RAM.

4. Pull-UP connect to Qn

5.  Read my last post. Rom disable for grant's logic or bit of a 273

6.  Grants logic is a FF,   one bit of 273 is a FF

Keep in mind that both circuits do the same thing with minor changes.
Tried to step you through the 4 chip logic
You understand the 4 chip version then you are very close to the 74LS670

Quote
Erm.. where?  Are you talking about D1-D3 on the schematic?
on 74LS670 pin GR(11) controls the tri-state of Qn outputs.

 74LS670
Think you understand your current ram chip.
You could think of the 74ls670 as two ram chips.
One ram chip is write only.
One chip is read only.
When you use write only chip to write a location say address 1 you can only read the data using the read only chip using address 1
The 74LS670 is like two ram chips but with only one storage location inside for an address.

Think you want to play and learn hardware using Z80
Z80 is also not bad learning software on.

For software side you can get more done using nice powerful tools.
For hardware side good hardware design is what makes it easer.

Grant's just a working computer with few chips. not a great hardware design.
Parts of design is for other microprocessers, still works with Z80 just not great.

MMU
   simple concept
      A circuit that lies about the address it uses.
      Here the MMU only stores address data used for the Lie.
      It can an often does store other data like.
        is this area accessable
        is this area writable.
        has this area been changed

The CPU asks for something by address.
   the MMU uses this address to access it memory. from this memory it gets the actual address to use with memory
  This takes time but can make a computer very powerful.
Even at the cost on having to add wait states for memory.

Think of what CP/M3  can try to do.
   that old slow floppy disk drive that is using 1024 byte sectors.
   CP/M programs want a 128 byte sector.
CP/M can read that 1024 byte sector from that slow floppy and put data in extra memory
Keep track of what changed and then write back to floppy if needed.
Many many things possible with more memory




 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #30 on: November 12, 2017, 10:44:30 AM »
Personally, I wouldn't use two '690 chips to map 4MB down to 64KB.   The benefit of the '690 is it allows a very simple MMU to be built to map 256KB down to 64KB in 16K pages. However its relatively slow so if you want to clock a modern Z80 clone as fast as possible it isn't a great choice.

I cant conceive of needing more than 1MB address space for a Z80 system
In the topic I linked to in the O.P.s earlier Z80 thread,  I contributed the concept of using a '486 era fast cache SRAM to do the mapping.  The spec was to map 1MB into the Z80 64KB in 4KB blocks.  Propagation delay was solely dependent on the SRAM used, possibly as low as 10ns. 

The smaller block size is far more versatile, and specifically makes it easier to work on large data sets, or implement a fast ROMDISK and RAMDISK, without any speed penalty, as the design could store 256 maps and, once a mapping was set up, you could select it or flip to another mapping with a single OUT instruction.  It mapped reads and writes separately for ease of copying ROM to RAM, and also to permit write protection of RAM.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #31 on: November 12, 2017, 01:27:01 PM »

nockieboy is trying to understand a MMU

I started with 4 simple chips
The storage chip(273) have a reset or clear input.
As reset/clear causes data to be 0, ROM is first and boot rom code is at 0-16k
Ram starts at 128k

The change from this to using an 74LS670 is
Using 4 I/O output addresses in place of two.
And a change from having a reset/clear input to using pull-ups and tri-state disabled outputs.
Disabled outputs with pull-ups causes output bits = 1
This change causes the boot rom to be at the highest block in memory.

The addition of a second 74LS670 becomes a simple step then when using 4 I/O output ports.
The benefit is a 4M address space when using 16k blocks, an upgrade from 256k
This shows that a few added bits can make a huge change in expended memory.

The logic of how these steps work is an important part to understanding an MMU.


nockieboy
  Grab a some paper and then work through this post

http://www.eevblog.com/forum/projects/z80-memory-banking-for-128k-mmu-design/msg1345498/#msg1345498
The drawing you create should be a big help in understanding both the 4 chip MMU and the 74ls670 version.
Think it will help a lot.

Next look at datasheet for 74LS670
http://www.ti.com/lit/ds/sdls193/sdls193.pdf
At top of page two is a logic drawing
Lets fix that drawing so that it makes sense as used in a MMU

Ra & Rb put these on right side inline with Wa & Wb
Gr put on   right side inline with Gw

You now have two address pins at top
a Ck input on left & a tri-state enable on right
Data pins at bottom.

Left side of chip is now Z80 I/O write inputs
Dn = data Z80 Data  D3-D0
W? = Address  A1,A0
Gw = Ck for write and =  Address + IORQ + WR

these pins are connected as a z80 output,
four i/o output addresses used
Data written is high expanded address to be used for the four 16k blocks
This data will become EA17,EA16,EA15,EA14


Right side is now MMU pins
Qn is expanded address to memory.   EA17,EA16,EA15,EA14
Rn is high address from Z80   A15, A14
Gr is output enable active low. When high Qn are in tri-state mode.


How it works
Z80 starts a memory cycle
Z80 puts address on address buss
This causes Rn to select 1 of the four data stores( the 16k area)
The data in store appears on Qn, this data is used as high part of expanded address.

How Z80 controls
The Z80 writes 4 bits of data into one of the four output addresses( an area)
The four addresses are area0 to area3

On power up
   Garbage is in storage.
   On power-up,  Qn is disabled by using Gr input,  A high level.
   With no output on Qn, pull-up resisters makes these pins = 1.
Write good data
   enable Qn output so data can be used, A low level on Gr.
     

On power-up with Qn disabled( and resistors pulling high each pin, each area is accessing

From
MMU      Z80                        MMU         Z80
0b1111  00000000000000  to 0b1111     11111111111111 a 16k area

The expanded address range of 0x3C000 to 0x3FFFF

with output disabled it is same as if Z80 wrote F in each of 4 locations

0-7 = Ram blocks
8-F = Rom blocks
Block F = Boot ROM code The highest 16k block.

The 4 chip version of MMU has
0-7 = Rom blocks
8-F = Ram blocks
Block 0 = Boot ROM code The lowest 16k block.

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #32 on: November 12, 2017, 10:57:37 PM »
I cant conceive of needing more than 1MB address space for a Z80 system
In the topic I linked to in the O.P.s earlier Z80 thread,  I contributed the concept of using a '486 era fast cache SRAM to do the mapping.  The spec was to map 1MB into the Z80 64KB in 4KB blocks.  Propagation delay was solely dependent on the SRAM used, possibly as low as 10ns. 

Crikey, I'd forgotten all about that thread! That was a long time ago.. (well, it feels like it!)  :o

Okay, I think I'm making progress with this 2-chip MMU design, following Ian.M's suggestions so far:



I have really only two questions regarding this circuit now:

1) Where do those pull-up/downs go to select ROM bank 0 (lowest 16K in ROM) for Area 0 (lowest 16K in memory space) and RAM bank 1 (16-32K in RAM) for Area 1 (16-32K in memory space) on power-up?? (That's the minimum requirement to get the monitor running - once running, it can set up the memory as it likes.)

2) Ian.M - you state:

Drive '670 /WE and flipflop CLK in parallel from your port address decode logic which should include Z80 /WR.

My IO port address decode logic currently looks like this:



So I'm going to have to AND the Z80's ~WR line with the appropriate IO address select line from the 138 before it goes to the 670 ~WE and 7474 CLK?

Also, on a tangent, I think I'm going to have to add another 138 to decode some more addresses - I'm running low on IO lines! (only 2 left..)  :o  Although this MMU design would free up the IO line used currently to switch the ROM out in Grant's design...

nockieboy
  Grab a some paper and then work through this post

http://www.eevblog.com/forum/projects/z80-memory-banking-for-128k-mmu-design/msg1345498/#msg1345498
The drawing you create should be a big help in understanding both the 4 chip MMU and the 74ls670 version.
Think it will help a lot.

I got this, I'll break the crayons out and be right back...  ;D  The honest problem is I don't have 15 minutes to sit and focus on this at the moment (and it requires a LOT of focus due to my limited understanding) - I'm hoping to get some time during the week to work on getting my head around how to get the 670 doing what I want it to.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #33 on: November 12, 2017, 11:07:48 PM »
To get the 74LS670 to work
You need one output from the 273 connected so that a 0 makes the 74LS670 output goes tri-state.
OR
  You keep using grant's logic and have ROMDisabled connected to 74LS670 tri-state input pin 11.

Just noticed this, C, and your comment about needing the 74LS670 as it would be quicker.  Would the LS version work okay with the rest of my chips which are all HCT components?

Also - the comment re: the 273.  I've not got a 273 in the current MMU design (see post above) - would the current design do what I need it to do and switch the ROM so I can remove Grant's ROM switching circuit?
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #34 on: November 12, 2017, 11:40:32 PM »
The 74HC670 looks to be slower then the 74LS670.
So both would work an slow Z80 clock speeds.
As you increase the Z80 clock speed, you have less time from when the Z80 address lines are changing and then MREQ going active.

So at some Z80 CK speed  slower stops working correctly. Faster gets you higher clock speeds
I have not added up the times but I think 2 & 4 meg should be ok

At some point, you would need to add a time delay to MREQ to go higher.
Two inverters are a time delay.
The 74LS670 is not for a 16-20 meg z80 clock if you want fast computer.

Think you will be fine and rememver easy to change on breadboard.

HCT is a TTL level CHIP the 74LS670 will be fine here.

If you have two 273's and 2 253's you have what you need.

A change to 74LS670 is very small. need 74LS670 and pull-ups.

A 273 and inverter will work to control tri-state
Grant's rom disable would work.


Some clean up of grant's would make playing with hardware easer.

More quick
 
« Last Edit: November 13, 2017, 02:34:49 AM by C »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #35 on: November 12, 2017, 11:46:27 PM »
Good morning nockieboy

See if I can make it better

Your last drawing is the 74ls670
Note that you need the LS not the HC

The Gr pin  of 74ls670 is like the EO pin of the 253 in  your previous drawing

Ra & Rb are the select inputs of the 253

For the 74LS670 the 253's data inputs do not show. But both are connected to storage.

74LS670 Qn outputs are same as 253 outputs. With just 2 outputs ber 253, need two to get four outputs.

So 253 pins match 74LS670 With storage connection shown for 253 and hidden inside for 74LS670

To get the 273 to match it's four 273's but only 4 input & output bits.

74LS670 Dn inputs are the 273 data inputs

The 74LS670 has part of address decoder you need to connect to get 4 273's working
This is one half of a 139 decoder.
74ls670 Wa,Wb are decoder inputs of 139
The 139 decoder has an enable pin, the 273 have a Ck pin, These are all connected together and are these become Gr input of 74LS670

Just noticed
See Gw & Gr in some data sheets and Ew & Er in others they are same pins.

So The four chip version lets you see some of what is inside the 74LS670

If you do not use the clear input to 273 and use the tri-state output of 253 you have a 74LS670

 

« Last Edit: November 13, 2017, 02:38:08 AM by C »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #36 on: November 12, 2017, 11:53:21 PM »

PULL-UP- resistors
The Pull-up resistors put a valid logic level on inputs of memory chips isstead of letting them flop around.
Connect to Output of MMU
Qn on 74LS670
Outputs of 253 for that version


 

Connect to address inputs of your memory chips
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #37 on: November 13, 2017, 12:02:23 AM »
Q1: The pullups/pulldowns go on the four extended address bits EA14-EA17 on the physical memory side of the MMU circuit.  If all the memory chips and logic that has those lines as inputs have normal CMOS input thresholds (20%, 80%) you can use pullups and pulldowns to set the default value of that nibble freely.  However if any of them have TTL compatible input thresholds you should *ONLY* use pullups, which forces you to put the ROM at the top of the memory map and the boot block at the top of the ROM as 'C' has been recommending.   Because the extended address bus is inactive from /RESET until your code enables it, the pullups/pulldowns can be a relatively high value as their lines are static until enabled.  10K should work nicely.  N.B the effect of switching back to BOOT mode on a screaming fast Z80 system would be unpredictable.   10K might not pull the lines to the correct level in time for the next /M1 instruction fetch.  Don't do that unless you are already executing from the BOOT block mapped in page 0.

Q2: Propagation delay in the I/O address decoder is a bitch.  Personally, I'd start with a pair of 74AC138* chips totally decoding the high nibble of the 8 bit I/O address (A4-A7), + /IORQ (to /E1).  Connect A7 to /E2 of the first chip and E3 of the second. Don't include /M1.  Its only active with /IORQ in IM2 interrupt acknowledge cycles, with /RD and /WR inactive.   That will give you 16 active low lines that each correspond to 16 consecutive I/O addresses.   Within each 16 address block, you can then decode right down to single address level and include /RD or /WR with another '138.   

On speed of 74xx670 chips - they aren't that fast - if you are building a screaming fast system using a Z80 clone possibly with interleaved video memory access you need to use something much better.  That's what drove the topic I originally pointed you at towards '486 era cache SRAM to do the MMU mapping, in spite of the complexity of it only having a single address bus and data bus.  There was just no other way of getting the MMU propagation delay down to 10ns while retaining 5V logic. 

If you need to interface Z80 peripheral chips that directly take /IORQ, /RD and /WR, the above doesn't give enough setup time for /CS because /IORQ was included in the first decode.   A single '138 directly on the address bus lets you decode 6 bits, with the constraint that one must be high and two low, and will support eight Z80 peripheral chips, with A0 and A1 passed through to the chip for register selection.

Take care to avoid address conflicts between the raw I/O decoded addresses and addresses decoded for Z80 peripheral chips.

* 74AC series parts have brutally fast edges on their outputs.  6ns is typical.  Use a ground plane and make sure each package has good local decoupling.  You may need to add source termination and RC load termination of long lines to reduce reflections and control EMI.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #38 on: November 13, 2017, 12:12:56 AM »

1) Where do those pull-up/downs go to select ROM bank 0 (lowest 16K in ROM) for Area 0 (lowest 16K in memory space) and RAM bank 1 (16-32K in RAM) for Area 1 (16-32K in memory space) on power-up?? (That's the minimum requirement to get the monitor running - once running, it can set up the memory as it likes.)

You only get ROM at low address range if you use pull-DOWN resistors.
Pull-Down not a good idea when using LS or HCT

Do this
make two versions of your power up boot program
Put one copy at 0-16k in your ROM
Have it stat "From Low Rom Area"

Put a second copy in your Rom at the highest 16K area
Just changet "From Low Rom Area"
to
   "From HI  Rom Area"

your Boot ROM is now good if your code is good.
Will work with Grant's
Will work with Expanded 0-16k
Will work with Expanded 256-16k to 256k the highest block

The code is the same only the message changed.
 
The following users thanked this post: Ian.M

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #39 on: November 13, 2017, 02:13:49 AM »
Address decoders

To keep math easy need some numbers, these ARE MADE UP.

When data changes on a bus, any buss, it is a BIG MESS.

First you have the device trying to change the data not changing it at same time.
Then you have differences in signal paths, load on pins, and a whole bunch of other things.

Safe thing to think
Buss has stable data.
When bus starts to change, the data goes to crap, IT is UN-KNOWN.
Some time later the data lines get to a stable state, but NOT at same time.

If you have a decoder chip looking at the buss, many of the outputs will bounce up and down. With out careful design of decoder some outputs could take less time to decode then others.

The decoder chips like the 138 are built to handle this problem but needs a signal stating that BUSS is now stable.

For Z80 this is MREQ or IORQ for address buss.
Now at a slow Z80 clock speed the address buss should become stable a long time before MREQ or IORQ
It is not hard to delay MREQ or IORQ, but you can not make these happen before they do.
Now if you KNOW that MREQ or IORQ happens before the address buss is stable, it is not a problem if you add the correct delay to fix this.
If you look at Z80 Datasheet, At high Z80 clock speeds the 20m Z80 does this.

What you want is a nice clean change on the CS pin of your SIO or memory chip.
To get this MREQ or IORQ should enable the outputs of the decoder chip that is connected to the SIO or memory chip.
Look at the Z80 peripheral chips, they want CS to be a range of 4 I/O addresses.
So
  A0 & A1 goes to Z80 peripheral chip
For full address decode A2,A3<A4 goes to 138
The final output enable should connect to IORQ
This leaves A5,A6,A7 not decoded yet for full address decode.
Lets use some simple numbers to make the picture clear

Lets say that it takes 15 Ns for output to change based on A2-A4.
and it takes 10 ns IORQ change to get to outputs to enable them

As long as IORQ happens 5 ns after the addresses have stopped changing you get no glitches on the output. A glitch is the output going low and back high in this case before the stable low level.

Now to get full address decode you need a second 138 for A5,A6,A7
With the output of this chip going to one of the first enables you have the following
A5,A6,A7 take 15 ns to change first 138 output then 10 Ns enable time of second 138.

with this logic A5,A6,A7 need to be stable 25 ns before output to SIO.
This is 15 ns before IORQ.
If you connect IORQ to A5,A6,A7 you create a problem
  output of this decoder is 10 ns after IORQ & another 10 ns delay happens with second decoder. The CS of the SIO is now delayed 20 ns instead of 10 ns

Now some chips when used for OUTPUT also need WR
Chips like 273 need this.
The 74LS670 needs this.
Connecting a AND gate to combine WR AND the address + IORQ above will add the AND gate delay time to the signal.
If you can connect WR to the decoder you can save this time.

So when designing a computer it is not just getting the logic correct.
It is getting the Logic correct with out GLITCHES.
It is getting the timing correct to prevent glitches and making the connected chip happy.
AND Z80 happy with the connected circuit.

Note that I used 10 ns and 15 Ns above, You always want some stable time and not run on ragged edge of times. 

Now if you have a need for just IORQ enabled chip selects and IORQ + /wr chip selects, you might want to run parallel decoders to do this.
Going parallel means that the Z80 has to drive more chips which slows changes but can save having to go through more levels of decode.
The Z80 has a limit on what it can drive

Remember that time is not just hardware.
Good hardware lets you use less software to get the job done.
Less software = faster computer.

Now in past I talked about software
Last I saw your SIO init code it had data values embedded in the code.
lan.M's example code does this.
It is easer to show details when doing this, but you can not easy have program change the data.
The data is all over the place when you need a change and often this means you need to run the assembler again.

This is where having data tables is your friend.

For your SIO init code
Load register with address of a table of bytes to be sent to SIO.
Load a register with What SIO
You can now have a common sub that will INIT any SIO.

For MMU this can also be handy
The same sub could handle part of the inital load to MMU
And same sub could then be used when areas need to be changed.

If what CP/M3 wants does not match what your MMU needs then the table can handle most of the problems.

So for MMU
First thing is get ONE MMU working. This is the big step.
After that it is small change for the different versions of MMU.

You could have software that will work with any version with out software change.

When you look at the old ways, try to understand then in the time when used.
Is there a better way using todays chips.

An example
   my first ram memory board used 2kx1 chips and cost a lot.
A simple 8k memory board was 2kx1 X 8 X 4   That is 32 chips.  This board ran HOT, it was almost a bread toaster.
When the 2k x 8 chip came out, that board saved a lot of chips and a lot of power.
So when you used 128k chips it was a smart move and saved you money. Now if you think about it 512k could be better yet.

The 48k bank select was a way to got old computers to work with few changes.
Big thing was Many boards with only a 16 bit address bus and no easy way to add more address lines.
Having 4 16k areas lets you look like you have 48k banks and use the huge memory chips of today. That old hardware will becomes a mess when connected to huge memory of today.


 





   
« Last Edit: November 13, 2017, 02:32:24 AM by C »
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #40 on: November 13, 2017, 09:42:42 AM »
Okay, here's the updated schematic with the 74LS670:



Are the pull-ups correct?  They should make the very top 16KB bank of the 128KB ROM appear in Area 0 (bottom 0-16K page of memory space) on power-up.

The issue I can see is how do I set the default power-on state of Q4 (the RAM/~ROM select line) - technically it should be pulled low, but apparently that's a 'bad thing'TM?

Let me know what changes I need to make to the MMU circuit above (if any), then I'll start looking at the IO decoder circuit as I'm going to have to make changes there also.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #41 on: November 13, 2017, 12:28:42 PM »
Resistors on all four pins Q1-Q4

The pull up on Q4 should enable ROM.

=====

Gr is High for tri-state so at power up reset the FF output connected should a 1 HIGH

Here you have a lot of options using the 74
Would be nice when you write to this port for D7 to be low normally so when clocked by I/O write you will get a state on the two outputs. Here you want a low level on
D7 low on I/O write which makes  Gr  = 0   The Q output.

At power UP you then  write the first 4 times with D7 high.
Then turn on MMU by a write with D7 low

So with this being what you want for normal, you have a choice of preseting this chip on power up or clearing this chip on power up.
So if I am thinking correct Power Up preset Sets the FF to cause Q= 1 -> Gr which tri-states 74LS670 outputs.
So if your RESET goes Low at power up and is connected to preset you are good.

This matches lam.M

From what I see in drawing add the Q4 resistor

 You match lan.M post for port use.

======

In place of 74
Now If you are going to have a 273 that is reset at power up you could use a bit there in place of 74 FF. BUT the 273 only resets to 0 so you would need and inverter between 273 bit and Gr.
And to be complete you could use grant's existing logic to do this. Not my choice unless you want to use it while making the change.

Would suggest you put this on separate breadboard or on memory breadboard.
You could leave the Q1-Q4 disconnected from memory and do some tests to verify you have built this correctly.

========
Decoder
   remember that you do not have to use all outputs.
If you have nothing connected then nothing will respond to that address.
You could build a new decoder and slowly move outputs from U5 to new.

In the future, think you would like a decoder for
One address I/O Write      (273,374  & lan.M MMU )
One address I/O Read
Four address I/O  for (SIO, CTC PIO)

Then I think the CF card is using 8 addresses. Would need to look in the software to verify it is using 8 and not less.
You could OR two 4 address outputs, but Need to test to see if it works with added delay of OR gate.

Need to keep track of what is connected and how much load each thing adds to Z80 output. Z80 has limited output.
« Last Edit: November 13, 2017, 12:30:41 PM by C »
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #42 on: November 13, 2017, 03:53:45 PM »
No. the ROM has /CE and the RAM has CE2.  Pulling up EA17 (aka Q4, RAM/ROM_SELECT) would select the RAM at booot - pretty pointless.  However the RAM and ROM *PROBABLY* have CMOS input thresholds.  If so, a pulldown is legitimate.   If they have TTL thresholds, (or worse there is an actual bipolar TTL gate input on that line), then stick a pullup on Q4 and follow it with a CMOS inverter to drive the ROM /CE and RAM CE2.  That would also swap the positions of the ROM and RAM in the memory map.

If you go with my suggestion for decoders, you get at the top level 16 address blocks, so no problem hooking up a CF card with three address lines.  However a CF card has TWO chip select lines, that select different register sets so you still need to combine A3 with the 16 address block /CS from the top level '138.
« Last Edit: November 13, 2017, 04:07:08 PM by Ian.M »
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #43 on: November 14, 2017, 05:25:52 AM »
No. the ROM has /CE and the RAM has CE2.  Pulling up EA17 (aka Q4, RAM/ROM_SELECT) would select the RAM at booot - pretty pointless.

Yeah, that was my concern. Could always use an inverter, but I'd be miffed if I have to add another chip to use one inverter on it...  :palm:

However the RAM and ROM *PROBABLY* have CMOS input thresholds.  If so, a pulldown is legitimate.   If they have TTL thresholds, (or worse there is an actual bipolar TTL gate input on that line), then stick a pullup on Q4 and follow it with a CMOS inverter to drive the ROM /CE and RAM CE2.  That would also swap the positions of the ROM and RAM in the memory map.

Okay well, this sounds like it could make a huge difference - I'm going to pour over the datasheets for the RAM and ROM tonight to see if I can work out if they're CMOS or not.  Will it say 'CMOS/TTL-level inputs', or am I looking for something in particular?

If you go with my suggestion for decoders, you get at the top level 16 address blocks, so no problem hooking up a CF card with three address lines.  However a CF card has TWO chip select lines, that select different register sets so you still need to combine A3 with the 16 address block /CS from the top level '138.

I was a little befuddled by the decoder explanation, I'll admit - I think the considerations around potential timing issues are worrying and distracting me - but I'm not giving that much thought at the moment as I want to pin down the MMU function and design first, then I'll turn my full attention to modifying the IO decoder.

Gr is High for tri-state so at power up reset the FF output connected should a 1 HIGH

Here you have a lot of options using the 74
Would be nice when you write to this port for D7 to be low normally so when clocked by I/O write you will get a state on the two outputs. Here you want a low level on
D7 low on I/O write which makes  Gr  = 0   The Q output.

At power UP you then  write the first 4 times with D7 high.
Then turn on MMU by a write with D7 low

So with this being what you want for normal, you have a choice of preseting this chip on power up or clearing this chip on power up.
So if I am thinking correct Power Up preset Sets the FF to cause Q= 1 -> Gr which tri-states 74LS670 outputs.
So if your RESET goes Low at power up and is connected to preset you are good.

Sorry C, I'm struggling with the English in this one. So you're saying that at power-up, ideally I want the 74 flip-flop to be outputting HIGH to tri-state the 670's outputs?  Then I guess the pull-ups will work their magic and the top bank in ROM will appear in the first area of memory space?

(How) can I preset the output of the 7474? The design only uses D0-D5 currently - how would I implement your suggestion about using D7 to enable/disable the 670?

In place of 74
Now If you are going to have a 273 that is reset at power up you could use a bit there in place of 74 FF. BUT the 273 only resets to 0 so you would need and inverter between 273 bit and Gr.
And to be complete you could use grant's existing logic to do this. Not my choice unless you want to use it while making the change.

No, I'm going with this design currently so I won't be touching any 273's.

Would suggest you put this on separate breadboard or on memory breadboard.
You could leave the Q1-Q4 disconnected from memory and do some tests to verify you have built this correctly.

Absolutely - sounds like a good idea.  :-+

Decoder
   remember that you do not have to use all outputs.
If you have nothing connected then nothing will respond to that address.
You could build a new decoder and slowly move outputs from U5 to new.

In the future, think you would like a decoder for
One address I/O Write      (273,374  & lan.M MMU )
One address I/O Read
Four address I/O  for (SIO, CTC PIO)

Then I think the CF card is using 8 addresses. Would need to look in the software to verify it is using 8 and not less.
You could OR two 4 address outputs, but Need to test to see if it works with added delay of OR gate.

Need to keep track of what is connected and how much load each thing adds to Z80 output. Z80 has limited output.


Another good idea re: building a new decoder and swapping lines over to it from U5 one by one. I'm running out of space though!  :o

Currently I've got the ROM/RAM select circuit, SIO/2, CTC, PIO and CompactFlash running from the 138 IO decoder.  I'll be adding the AY PSG after the MMU, so that's two more things to add.  These select lines are all driven by the 138, though - the Z80 (it's CMOS - Z84C008) itself drives the address and data buses and a handful of HCT logic chips, but I hear you loud and clear.  I have plans to add buffers to the address and data buses, but won't these add a delay into the circuit?
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #44 on: November 14, 2017, 06:04:17 AM »
However the RAM and ROM *PROBABLY* have CMOS input thresholds.  If so, a pulldown is legitimate.   If they have TTL thresholds, (or worse there is an actual bipolar TTL gate input on that line), then stick a pullup on Q4 and follow it with a CMOS inverter to drive the ROM /CE and RAM CE2.  That would also swap the positions of the ROM and RAM in the memory map.

Errr... okay, both the datasheets for the ROM and RAM mention TTL IO compatibility... not sure if that is a definite no to the question of whether they have CMOS input thresholds, as I don't know what I'm looking for.  Here's the relevant datasheets, anyway:

ROM: 39SF010A EEPROM
RAM: AS6C1008-55PCN SRAM
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #45 on: November 14, 2017, 06:11:18 AM »
TTL thresholds, and the RAM's logic 0 threshold is only 0.6V, so you *should* use an inverter.   You can use any inverting gate with its inputs strapped together.    If you try to use a resistor it will probably be unreliable.
 
The following users thanked this post: nockieboy

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #46 on: November 14, 2017, 10:23:15 AM »
Okay, so this is how the MMU is looking now:



Can I just confirm what the memory map now looks like and that the IO addressing is the same as you previously stated, Ian.M?

So RAM is now 0-128KB and ROM effectively now occupies 128-256KB in physical memory space?  On power-on, the Z80 will see the top 16KB bank (112-128K) of ROM as area 0 (0-16K) in memory space?
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #47 on: November 14, 2017, 11:08:38 AM »

Yes

A14 & A15 connect to 74LS670.
Output of 74LS670 is disabled. (rri-state)
Resistors supply high address lines levels.

So At power up Z80 sees four copies of the top 16k bank

You write good data in to 74LS670 with it still disabled.

You then enable 74ls670
Z80 A14 & A15 noiw controls what is on the 4 address lines via 74LS670

 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #48 on: November 14, 2017, 11:42:42 PM »

You could have a lable on Q4      EA17

Might make it easer for some one to understand.  Q4 is an expanded address line, here used as ram/rom select.

How you doing understanding a MMU?



Now some things you might not have noticed.

There is JEDEC Standard for a – 32-pin PDIP
Part of standard covers the pins, part software for non tam/rom , parts like flash eeprom.

The datasheet for your flash rom table 4 shows this for a 32 pin socket.  If you were planning a PC board, with some care, it could be used with many sizes of chips.

Note the software steps for your Flash Rom to write data again part of JEDEC

So table 4 gives you a list of pins to check how the use of pins change with size
pin 30, pin 1 , pin

I would wire up pin 31 to both chips so in the future you can write to flash using Z80.

You are using a inverter here. If you had more 128k chips, you should use a decoder like 138.

Older memory chips do not support the way these chips are used and you would have MREQ connected to decoder enable instead of where MREQ is connected now.
 
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #49 on: November 15, 2017, 12:28:10 AM »
A cheap and easy way of adding more FLASH ROM would be to connect the remaining unused data bit at the MMU port address to the other half of the boot mode flipflop chip, in exactly the same way.   Then instead of the inverter  between  EA17 and the /CS line to the ROM, take the Q and /Q from the new flipflop, each to one input of a pair of NAND gates, with their other inputs from EA17.  That gives you two ROM /CS signals, each suitable for a 128K chip without increasing your glue logic chip count.   At boot, the flipflop would be set, so the NAND fed with Q would generate the active /CS. 

It would have the limitation that you cant map blocks from both ROMs simultaneously, and when you switch that bit, *ALL* ROM mapped pages flip to the other ROM chip, but that can be handled by *either* duplicating the critical boot block and BIOS in both chips, leaving you with 224K free, *or* copying the BIOS to RAM, giving you 240K free. Both give  enough space for a  CP/M Plus system + selected utilities on ROMdisk.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #50 on: November 15, 2017, 02:45:16 AM »
Okay, I've skipped ahead a little and started thinking about the IO decode circuit, as below, before I read the last two comments from C and Ian.M.



Above is how I think the 138 should be wired?  Is that right?  Should I remove ~M1 and/or ~IORQ from the 138? (Thinking about timings..)

A cheap and easy way of adding more FLASH ROM would be to connect the remaining unused data bit at the MMU port address to the other half of the boot mode flipflop chip, in exactly the same way.   Then instead of the inverter  between  EA17 and the /CS line to the ROM, take the Q and /Q from the new flipflop, each to one input of a pair of NAND gates, with their other inputs from EA17.  That gives you two ROM /CS signals, each suitable for a 128K chip without increasing your glue logic chip count.   At boot, the flipflop would be set, so the NAND fed with Q would generate the active /CS.

Interesting point - something I might think about later, but at the moment I can't see a use for an additional 128K ROM... Though, yes I know, that might change.  ;)

How you doing understanding a MMU?

Won't have time to sit down and the sketch out the MMU picture into later in the week.  Until then I'm grabbing spare time where I can to update the MMU / IO decode schematics with the progress in this forum.  :-+

Now some things you might not have noticed.

There is JEDEC Standard for a – 32-pin PDIP
Part of standard covers the pins, part software for non tam/rom , parts like flash eeprom.

The datasheet for your flash rom table 4 shows this for a 32 pin socket.  If you were planning a PC board, with some care, it could be used with many sizes of chips.

Note the software steps for your Flash Rom to write data again part of JEDEC

So table 4 gives you a list of pins to check how the use of pins change with size
pin 30, pin 1 , pin

I would wire up pin 31 to both chips so in the future you can write to flash using Z80.

You are using a inverter here. If you had more 128k chips, you should use a decoder like 138.

Older memory chips do not support the way these chips are used and you would have MREQ connected to decoder enable instead of where MREQ is connected now.

Yes, I was aware of the JEDEC standard and the possibility that the EEPROM could be in-circuit programmed, but it's something I've never gotten round to looking at.  To be honest, I've thought of it as a lot of work just to remove the minor annoyance of removing the EEPROM from the ZIF and putting it into my EEPROM programmer, then swapping it back afterwards.  However, as and when (and if) I get round to putting this onto a proper PCB, then in-circuit programming would remove the need for a ZIF on the PCB and allow me to just pop the EEPROM into a DIL holder and leave it there, but carry on development.  Nice idea - something I'll add to the end of my wish-list.  :-+
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #51 on: November 15, 2017, 03:10:05 AM »

A list\
IORQ & RD  = i/o read     input
IORQ & WR  = I/O write   output

IORQ & M1 = Interrupt ack   

The second item is unique
    The Z80 never makes WR & RD active at same time.

Remove M1

Now an option
Connect WR to 138 and you have a Z80 I/O OUTPUT decoder.
You could then connect MMU directly to an output pin.
You could also connect 7 other 273 or 374 chips for more output bits.

With RD connected to decoder you have signal needed to read a 374 when connected to 374 OE

So think a bit
A 138 decodes 8 addresses.
The MMU and other chips need WR added to write data
The output of your U1 is 8 addresses.
If U3 is a 138 you would have 8 one address outputs. You could use one for MMU and have 7 more just waiting to be connected for more output chips.

.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #52 on: November 15, 2017, 03:28:32 AM »

You have been working with Grat's software for a while now.

Have you seen Grant's code use any thing other than
 OUT to address 0H with some data value?

If this is true then you can connect the second 138 to
the original U5 pin 13 and still leave Grants logic connected to second 138 pin 15.

You now have 7 more outputs on second 138 that could connect to MMU.


This would let you run as you are now with added 138.

You could then start adding MMU circuit and test it with a working computer.

On software side you would leave grant's code in place and start adding for the MMU.

When all tests are complete
   Change memory connections from Grant's logic to MMU logic.
With software in place this will work.

When working clean-up and remove some of Grant's logic.


 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #53 on: November 15, 2017, 10:27:44 AM »
You have been working with Grat's software for a while now.

Have you seen Grant's code use any thing other than
 OUT to address 0H with some data value?

It uses:

Code: [Select]
LD A,01
OUT (38h),A

exclusively to switch the ROM off.  There's no way to switch it back on in Grant's circuit, so it doesn't matter value is subsequently written to 38h afterwards.

A list\
IORQ & RD  = i/o read     input
IORQ & WR  = I/O write   output

IORQ & M1 = Interrupt ack   

The second item is unique
    The Z80 never makes WR & RD active at same time.

Remove M1

Okay, so I just need to remove M1 then.  I'll post the updated decoder schematic tomorrow.  IORQ and M1 were added to the 138 as a result of this discussion here about adding the AY sound chip - Z80 Homebrew Computer - fault finding.

Turns out the schematic I've been using for the IO decoder here isn't 100% accurate.  Below is what the decoder looks like in my current setup:



I'll get this updated and posted here tomorrow with M1 removed - unless anyone can head me off at the pass and let me know if there's going to be any problems running the MMU from Y7?
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #54 on: November 15, 2017, 11:00:05 AM »

Let me put it this way
M1 is not needed when you follow Z80 rules.

What are Z80 rules?
IORQ & RD is an I/O read.
IORQ & WR is an I/O write

When you have something that does not follow the rules you can have a problem
Not Z80 rules
IORQ & not RD     this is not a valid select for a Z80 I/O write
IORQ & not WR    this is not a valid select for a Z80 I/O read

M1 will not hurt any thing just that If needed it is a sign of some poor interface.

AY sound could need M1 so leave it connected


Suggest that you connect a new 138
A0 -> A pin 1
A1 -> B pin 2
A2 -> C pin 3
Wr -> E3 pin 5
pull-up E1 pin 6
current 138 Y7 pin 7  38-3F to new 138 E2 pin 4
Grants that was connected to current 138 Y7 move to new 138 Y0 pin 15

You have 7 outputs that will work for MMU pick one.

In summary:
 you have removed connections to grant's U5 Y7 pin 7 and moved these connections to a new 138 Y0 pin 15
You have connected grant's U5 Y7 pin 7 to new 138 E2 pin 4

New 138 decodes 8 addresses 38 - 3F as single address outputs
New 138 Y0 is output @ 38h

In your last post U1 = grant's U5
Every thing connected still works.
 
The following users thanked this post: nockieboy

Online nctnico

  • Super Contributor
  • ***
  • Posts: 12981
  • Country: nl
    • NCT Developments
Re: Z80 memory banking for 128K - MMU design
« Reply #55 on: November 15, 2017, 11:27:24 AM »
The Z80 based MSX2 computer had a memory exentension system:
http://msx.hansotten.com/do-it-yourself/memory-mappers-slots/
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #56 on: November 15, 2017, 11:37:51 AM »

You are trying to have many areas from the two main memory chips Used at many Z80 addresses.

the MSX2 is different
It has memory in side the computer  &
More memory in side cartridge.

The switch choice becomes INSIDE or Cartridge.

Need more info or is this enough?

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #57 on: November 16, 2017, 02:01:37 AM »
M1 will not hurt any thing just that If needed it is a sign of some poor interface.[/b]
AY sound could need M1 so leave it connected

Yes, I'm pretty sure I added it in due to some good reasoning by grumpydoc.

Suggest that you connect a new 138
A0 -> A pin 1
A1 -> B pin 2
A2 -> C pin 3
Wr -> E3 pin 5
pull-up E1 pin 6
current 138 Y7 pin 7  38-3F to new 138 E2 pin 4
Grants that was connected to current 138 Y7 move to new 138 Y0 pin 15

You have 7 outputs that will work for MMU pick one.

Hmm.. okay, well I've diverted from your suggestion only slightly, in that I've removed ~M1 from U5 (and also the OR that was gating A6 & A7 as an active-low enable pin was freed up) and kept the MMU select line on U5.  Instead, I've passed ~Y1 to pin 5 of U13 (a second 138 as you've suggested) which, along with ~M1 on pin 4 and A0-A2 on pins 1-3, will provide another 8 select lines (at least one of which I can use for the PSG.)

The reason I've done it this way and not your suggested way is because I didn't want the MMU's select line sitting behind another 138 (with the associated additional propagation delay that would introduce) and it would still be sitting behind the ~M1 line which would still be attached to U5.

Here's the updated decoder circuit - note that U13 won't be built in to the SBC until I finish the MMU entirely and move on to getting the PSG back on-board:

 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #58 on: November 16, 2017, 04:56:44 AM »
Quote
The reason I've done it this way and not your suggested way is because I didn't want the MMU's select line sitting behind another 138 (with the associated additional propagation delay that would introduce) and it would still be sitting behind the ~M1 line which would still be attached to U5.

Think a second on critical path
MMU is used for memory
The critical time path is Z80 A14 & A15 to Q1-Q4

so A0 -A13 go direct
A14 & A15 in the form of Qn are delayed by 74LS670

Read time is the critical path.

Z80 I/O write you have a lot of time.
So MMU being connected to U13 makes no difference for a memory cycle.

Think of 74LS670 being a memory chip
Read mode is used during the memory cycle.
RA & RB are address pins used
Qn is data outputs used
Gr is the OE

When updating the map you use write mode
WA &WB are address pins used
Dn is data input
Gw is write, chip select and address select input.

If you were using a cache memory chip
A14 & A15 & memory read time to data output is critical time.
the CS & OE are active all the time except for I/O write.
The other address inputs to this memory chip can be strapped to a level  and you would have one map like the 74LS670
If you connected other address inputs to the output of a chip, these are still static for memory cycle. But if you change output of chip in a I/O output you can switch between many different maps with just ONE i/o out.


So looking at your last
Y7 connection works fine with both chips.
When connected to U13 the MMU uses one output address a savings of 7.

So drawing looks OK
Think you know that U5 is working now.
so only changes are U12 & U13

To help with future logic designs, not to change what you have now.
U12 version with WR could be a 138 like I stated.
You could still have your special U12 that adds M1 connected to a different output


Now if you were trying for max speed, you would need to look again at the Z80 I/o chips.  CS for these chips is only address select.
For PIO
Quote
The internal control logic synchronizes the CPU
data bus to the peripheral device interfaces
Note the PIO has no WR pin
The chip gets the Z80 clock and by using the other inputs from Z80 can build an internal copy of what the missing Z80 pins would do.
the WR is an internal PIO creation.

the WR is an internal SIO creation.
the WR is an internal CTC creation.
These chips use a directly connected IORQ to qualify the address.

So if you want to plan for the future and higher Z80 clock speed
You want an address only decoder for all the Z80 I/O chips.
Each use 4 addresses
A2-A4 connected to 138 gives this
A4 when connected to E2 then gives a Low address A4 block of I/O
A4 when connected to E1 then gives a High address A4 block of I/O
Then by how you connect A5,A6 & A7 determines if you have one block or many mirrors of the blocks in I/O address space.

Back in the old days, You would have many boards connected to a buss. Each board would have it's decoder chips.
Most had jumpers that you strapped to set the boards address
A 138 could be connected to A5,A6 & A7 and you would connect one output of this decoder to one of the inputs of the four address decoder.A real pain in the ____.
Better designs used a  MAGNITUDE COMPARATOR like 74xx85
This change lets board designer put a dip switch on the edge of the board to set the board's address range.

The next step up from this is plug & play
There were many different versions
Some were based on what slot board was connected to. You could think that each slot had a output of a 138. The problem with this is some boards need a lot of addresses an some one or two addresses.
Then it would be nice if the CPU could know what was plugged into a slot.
Today a version of SPI is used to find out what is connected and to configure it.

So you need to make baby steps while thinking of future paths this might go.

The MMU is as simple as it can be for what you have.
In future it can be replaced or added to supporting your needs.

Like wise your decoder can be used as drawn or some changes for future.

The most important thing is TIME
Your RAM or ROM must have the proper data when Z80 reads it and must capture the Z80 data on write properly.
To check this you match data times then work back in time to see if some time is too short.
At some Z80 clock speed your circuit and memory will be too slow unless you add wait states.
And you should note that wait states is not a cure for every thing.
Wait states for example do not change time from when the data outputs of a device turn tri-state and when Z80 uses data buss for output.

Keep in mind that the Z80 does not have to run at an even MHZ. A Z80 can be faster with a little slower clock if memory changes from 1 wait state to 0 wait state.
A wait state is a step in time.

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #59 on: November 16, 2017, 08:59:10 AM »
Keep in mind that the Z80 does not have to run at an even MHZ. A Z80 can be faster with a little slower clock if memory changes from 1 wait state to 0 wait state.
A wait state is a step in time.

Okay, so that leads me on to a (vaguely) related question - is there such a thing as a programmable oscillator or frequency divider?  The reason I ask is that I can ch7ange the frequency of my SBC in software between 2, 4 or 8MHz, but I need a fixed 2MHz signal for the PSG, so whenever I change the system clock frequency, I'd like to be able to maintain a 2MHz frequency for the PSG.  I'm guessing a separate, dedicated 2MHz oscillator is probably the simplest and cheapest option...

EDIT:  ... except a separate oscillator will mean the PSG is running out of sync with the SBC's system clock, which could cause timing problems of its own. I've just done a quick search for 'programmable oscillator' - the cheapest I could find was like £50 (~$70?)  Ouch!

Ah, 74LS294 - programmable frequency divider?
« Last Edit: November 16, 2017, 09:13:31 AM by nockieboy »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #60 on: November 16, 2017, 10:41:23 AM »

Stage 1 is not worry about clock much

My thinking is that you are doing this to learn, and Z80 is not bad to learn on.
So a 4 Mhz machine or even a 2 Mhz is fine to learn on.
I would not try to use any Z80 chips with a clock greater then datasheet specifications.

The reason I mentioned time is you should be keeping track of what you have and looking for problems.
So when thinking critical paths  need numbers to know if it is critical.

Stage 2
work the numbers for what you have.
You could do this on paper but in long run a spreadsheet should be better.

Should not take you long to compute how fast the Z80 could run with your existing memory.
Then it should be a small step to see what the limit is with this MMU

Do the same for I/O

With the numbers you should then be able to tell how much margin you have a X z80 clock speed.

Then to make things more fun you should note that when the Z80 clock is less than max for that CPU you do not have to use a square wave to drive the chip.


So do your math's and get some numbers.

This is an important part of learning a CPU like Z80

Until this is on a PC board you should not try to get close to limits due to the use of breadboards.

spend some time to really understand the MMU
A lot will be handled by proper driver in CP/M3 but it would be good idea to think how the Z80 will work with this.

On software side
would be good idea to be able to run the CP/M3's relocating assembler for the bios code.




 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #61 on: November 20, 2017, 09:19:01 AM »
Quick update now that I've started building the MMU.  I've discovered an error in the IO manager's design - it now looks like this:



I'd previously used an AND gate to combine ~WR and ~Y7 to form the select line for the MMU - this clearly was the wrong gate to use, so I've swapped it for an OR gate instead.  I think ~IORQ was previously going into E3, which is the HIGH enable for the 138, so I've moved it to E2 which is a LOW enable.
 

Offline David Hess

  • Super Contributor
  • ***
  • Posts: 5471
  • Country: us
  • DavidH
Re: Z80 memory banking for 128K - MMU design
« Reply #62 on: November 20, 2017, 11:19:50 AM »
Okay, so that leads me on to a (vaguely) related question - is there such a thing as a programmable oscillator or frequency divider?  The reason I ask is that I can ch7ange the frequency of my SBC in software between 2, 4 or 8MHz, but I need a fixed 2MHz signal for the PSG, so whenever I change the system clock frequency, I'd like to be able to maintain a 2MHz frequency for the PSG.  I'm guessing a separate, dedicated 2MHz oscillator is probably the simplest and cheapest option...

EDIT:  ... except a separate oscillator will mean the PSG is running out of sync with the SBC's system clock, which could cause timing problems of its own. I've just done a quick search for 'programmable oscillator' - the cheapest I could find was like £50 (~$70?)  Ouch!

Ah, 74LS294 - programmable frequency divider?

As you identified, the clocks need to be synchronous unless special precautions are taken.

A synchronous counter can produce all of the needed clocks simultaneously and then a multiplexer can select which one is used.  Special precautions may be necessary to prevent glitches and clock violations.
 
The following users thanked this post: nockieboy

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #63 on: November 20, 2017, 08:26:47 PM »
As you identified, the clocks need to be synchronous unless special precautions are taken.

A synchronous counter can produce all of the needed clocks simultaneously and then a multiplexer can select which one is used.  Special precautions may be necessary to prevent glitches and clock violations.

Ah, thank you - hadn't thought about using a counter to divide the clock rate!  :-+  (I'm pretty new at this electronics stuff!)  :-//

So - would something like a 74LS163A be suitable?  I'm guessing I'd only need a 4-bit counter, rather than a decade counter, as I only have to get 2MHz from an 8, 4 or 2MHz system clock speed?  Unless I completely misunderstand the principle, a 4-bit counter would give me 4, 2, 1MHz and 500KHz from an 8MHz input clock, halving down accordingly with lower (4 or 2MHz) system clock speeds?
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #64 on: November 21, 2017, 06:12:24 AM »
Are you missing the first question?

Why change the Z80 clock speed?

If you have a good scope, running the Z80 at some divide by 2 ratio does not help much in testing.

What helps is changing the high & low times of the clock by a small amount.
Using a counter, you could decode the count and then have a multiplexer select that output. You could then reset the counter for next cycle.
Using a shift register gives you outputs that are counts. This removes decode glitches.
Using a 20Mhz master clock gives 50ns steps.
To keep glitches from Z80 clock, it is a good idea to use the output of a FF.
So a 20Mhz master clock gives a 10Mhz square wave clock to Z80.
50ns high, 50ns low = 10Mhz square wave
100ns high,50ns low = 7.5Mhz
100ns high, 100ns low = 5Mhz square wave
150ns high, 100ns low =
but you could have
150ns high & 50ns low
The non square wave lets you adjust address valid to MREQ valid for example.

These are still huge steps. Using a delay line would let you get smaller steps.

You need to remember also that you do not know what the Z80 is doing until after a delay when some Z80 pin changes.

A delay line gives more options but needs more chips.
A timer output from a microcontroller is an option if it has the controls needed and speed.

Easy thing to do is build your computer. Then use your scope to check signals to see how much faster it could run and get an oscillator that is just a little slower.


 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #65 on: November 21, 2017, 09:09:30 PM »
The Z80's clock is currently provided by a micro-controller - an Atmega328 running at 16MHz.  I can divide the clock by 2 for 8, 4, 2, 1 etc clock speeds.  It supplies an 8, 4 or 2 MHz clock to the SBC based on what the Z80 requests, defaulting to 4MHz at power-on, for no reason other than it was easy to add to the system and I learned a bit about changing the clock on the Atmega328 and adjusting for different clock speeds in software for the SIO and CTC (well, I'm still working on the CTC's timing!  ^-^)

But because the clock is variable, I was doing some research to see if there was an easy way to generate a constant 2MHz clock for the PSG.  I think a synchronous dual FF and multiplexer is the way to go (or just fix the system clock at xMHz.)
 

Offline David Hess

  • Super Contributor
  • ***
  • Posts: 5471
  • Country: us
  • DavidH
Re: Z80 memory banking for 128K - MMU design
« Reply #66 on: November 22, 2017, 02:56:57 AM »
So - would something like a 74LS163A be suitable?  I'm guessing I'd only need a 4-bit counter, rather than a decade counter, as I only have to get 2MHz from an 8, 4 or 2MHz system clock speed?  Unless I completely misunderstand the principle, a 4-bit counter would give me 4, 2, 1MHz and 500KHz from an 8MHz input clock, halving down accordingly with lower (4 or 2MHz) system clock speeds?

Some variation of the 74163 would be my first choice but it would be difficult to go wrong with any synchronous counter.  Using a synchronous counter can make things easier since all of the outputs change simultaneously relaxing the timing requirements of the logic which selects which output is used.
 
The following users thanked this post: nockieboy

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #67 on: November 23, 2017, 08:47:20 AM »
C - I've got my head around how the 670 works as the key component in the MMU now, thanks for taking the time to explain that to me.  :-+

I have a question about timings, though, which I'm not sure I can work out myself due to lack of experience and no idea where to start.  I'm still waiting for a 74LS670 to turn up in the post, so in the meantime I thought I'd throw the MMU together with a 74HCT670 for the fun of it, really and to see if it would work.  It doesn't.   :-BROKE

Now, I haven't had time to start searching for problems yet (so it could be a dodgy connection) but I thought I'd ask the obvious one before I break out the multimeter and vat of coffee; namely, is there any chance the HCT version of the 670 would work at 4MHz, or is it just too slow and that's the reason my SBC isn't booting?  I note that it's roughly half as fast as the LS version, but am not sure how that stacks with the ~M1 / ~RD timings etc.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #68 on: November 23, 2017, 09:06:33 AM »
Drop your system clock to 1MHz - if that doesn't fix it you've got a design or wiring problem or a bad chip.  The worst case propagation delay from the 74HCT670 in the A4:15 to EA14:17 path is under 50ns.   You'd have to sit down with Z80 timing diagrams for memory read and write and M1 opcode fetch + the specs for your memory chips to see how fast you can push the cycle time without wait states.  Don't forget to allow for propagation delays in any bus buffers.
 
The following users thanked this post: nockieboy

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #69 on: November 24, 2017, 01:09:38 AM »
Okay, the 74LS670's arrived in the post this morning and I've swapped the HCT 670 out for an LS version.  The SBC still won't boot, even when I drop the clock to 2MHz (the current minimum without tweaking the Arduino's software) I'm getting nothing but a blank console.  So I've started with basic fault-finding - found a D0 line that had become disconnected from the SIO/2 whilst I was removing some of the old (Grant's design) RAM/ROM select lines, but other than that I can't see anything else obviously wrong with the connections (it still won't boot.)  The next step is go through the schematics and make sure that every wire connects everything it should to everything else it should.

Before I started that, however, I thought I'd check the output of Q4 on the 670 to see if it was selecting the ROM as it should at boot.  Q4 shows 0v, which means the ROM will be disabled (the select line goes through an inverter, remember) and the Z80 will just see 64K of SRAM (and its associated random contents.)  1Q from the 74HCT74 FF is low, which is a good start.  I've done a little more cursory fault-checking with the 670 and found its supply voltage to be 4.2V - that's a bit on the low side for it to work, methinks?  :-//  My multi-meter isn't exactly the mutt's genitals, though and my skill using it and interpreting the results is about at the same level.  My USB volt meter widget is showing 5.00v at 0.17A, which seems reasonable to me.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #70 on: November 24, 2017, 01:40:59 AM »
Back to classic minimal Z80 fault finding - disable all memory by disconnecting their chip selects and strapping them inactive, and put 8x 10K pulldowns on the data bus so the Z80 only fetches NOP instructions.   It will cycle through all 64K of the address space in order, in under eight seconds at 2MHz.  Then its a matter of fun with a scope and/or logic analyser.

If all you've got is a logic probe or DMM, you'll have to customise your Arduino clock generator to let you run it for N clock pulses from release from reset (N=0 to 262144), then let you slow clock it or even toggle the clock manually, or the critical transitons will wizz past before you can study them.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #71 on: November 24, 2017, 02:13:13 AM »
From what I am reading, guess you did not do slow changes with verify steps to see each part is working.

So
 On power up 670 read output should be tristate
Qn pull-up resistors make these pins high.

Think of ways to test this

The 670 Gr pin high for example.

If you leave pull-up resistors connected to connected to memory &
disconnect Qn from memory, Z80 should see High 16k block of ROM,

Note that with all ROM the Z80 STACK is not working.

The Z80 boot software should be able to start and send a message to serial even with out STACK working.
 
Now if the MAD Software creator happened to write some code.
The code could write some values to the 670 and let you test the 670
Even with out the STACK working a JP will work.
At boot Z80 A14 & A15 = 0
If boot code jumps to the different areas what is on A14 & A15 will change

So code is running in area 0
do a jump where A14 & A15 change to area 1 with the lower bits set for instruction after the jump

With the boot code showing in all four areas, the Z80 could jump between the areas and stay in that area a while by doing a loop.

While looping you could output a message to serial.
The Z80 could try to write to memory & read memory.
Note that the ROM write has a software safety lock so even with ROM's WR pin connected, Rom should be un-changed.

You could get real fancy and do a software memory test on each area.
Think of this
Read a location
Write something different
Read the location again
Write back first read of location
If both reads match you have ROM
If Write value and following read value you have a RAM fault or ROM

ERROR in above line or not clear
If you write a value to memory you should read back same value if it is RAM
Note that you should use many different values to test RAM
00H followed by FFh changes all bits so you could have some shorts between data lines.
AAh followed by 55h is not bad



Crap meter should read close to same value for same voltage.
If you measure USB Voltage with crap meter then you should get very close to same value every where for 5v.

« Last Edit: November 24, 2017, 02:58:22 AM by C »
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #72 on: November 24, 2017, 03:17:14 AM »
From what I am reading, guess you did not do slow changes with verify steps to see each part is working.

Eeeerr...  :-[  Noooo... I DID wire it all up with just the Qn connections disconnected and the memory select lines intact and it worked, but that doesn't really prove a lot I guess.  :-//

EDIT: Oh, I made the modifications to the 138 IO manager and it all worked fine there too, before building the rest of the MMU.

Note that with all ROM the Z80 STACK is not working.

The Z80 boot software should be able to start and send a message to serial even with out STACK working.

Yes, that did concern me a little when I was modifying the boot code for the ROM.  At startup, there's an army of EQUates and DSs reserving space for variables, but they're little more than labels the assembler uses for memory addresses to store values, so with an all-ROM memory they shouldn't cause any problems, right?

After the EQU's and DSs, at the start of the ROM effectively,  the code does this:

Code: [Select]
;------------------------------------------------------------------------------
;                         START OF MONITOR ROM
;------------------------------------------------------------------------------
MON .ORG $0000 ; MONITOR ROM RESET VECTOR
;------------------------------------------------------------------------------
; Reset
;------------------------------------------------------------------------------
RST00 DI ; Disable INTerrupts
JP MINIT ; Initialize Hardware and go

So it jumps to MINIT, which does this:

Code: [Select]
MINIT:
; Initialise MMU
LD C,MMU_IO ; Set C to IO port of MMU
LD A,$8F ; MMU disabled, Page 0 = Bank 0F
OUT (C),A
LD A,$91 ; MMU disabled, Page 1 = Bank 01
OUT (C),A
LD A,$A2 ; MMU disabled, Page 2 = Bank 02
OUT (C),A
LD A,$33 ; MMU enabled, Page 3 = Bank 03
OUT (C),A
LD A,$3 ; Set MMU_Lock byte so that Areas 0 and 1 are locked
LD (MMU_Lock),A ; from inadvertant re-mapping by the BANK command

LD    SP,MSTACK ; Set the Stack Pointer
LD HL,serABuf ; Set up Serial A buffer
LD (serAInPtr),HL ; with In and Read pointers
LD (serARdPtr),HL
LD HL,serBBuf ; Ditto for Serial B
LD (serBInPtr),HL
LD (serBRdPtr),HL
XOR A ; 0 to accumulator
LD (serABufUsed),A ; Set both buffer sizes to zero
LD (serBBufUsed),A

So the first commands to execute, aside from the initial JP, are to set up the MMU and memory space, so the rest of the monitor code will run normally (and starts by setting up the stack area in a newly-assigned RAM bank.)  That's the idea, anyway.

Is that all okay to run without a stack?

Now if the MAD Software creator happened to write some code.
The code could write some values to the 670 and let you test the 670
Even with out the STACK working a JP will work.
At boot Z80 A14 & A15 = 0
If boot code jumps to the different areas what is on A14 & A15 will change

So code is running in area 0
do a jump where A14 & A15 change to area 1 with the lower bits set for instruction after the jump

With the boot code showing in all four areas, the Z80 could jump between the areas and stay in that area a while by doing a loop.

While looping you could output a message to serial.
The Z80 could try to write to memory & read memory.
Note that the ROM write has a software safety lock so even with ROM's WR pin connected, Rom should be un-changed.

Okay, sounds like a plan.  :-+

Crap meter should read close to same value for same voltage.
If you measure USB Voltage with crap meter then you should get very close to same value every where for 5v.

Yeah, I'm not sure about the issue there.  If there really is only 4.2V at the 670, that could be a problem.  I'll look into it (along with the software edits you've mentioned) later this week when I have some time. Thanks. :)
« Last Edit: November 24, 2017, 03:24:03 AM by nockieboy »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #73 on: November 24, 2017, 05:43:30 AM »
I do not see a problem with your code

Interrupt code will not work with out a stack in ram just so you know.

You can use the SIO with out interrupts be enabled.

One handy thing to have in software is a string output.
The C language uses a zero byte at end of string to determine the string length, but this prevents output of a zero byte

Other languages put a byte or word at the beginning that has number of characters/bytes to send. This way a Zero is a valid byte in string.
If you look at code for SIO init you could have a stream of bytes.

SIO_INITA:
; init channel A
length,  register, value, register, value
SIO_INITB:
; init channel B
length,  register, value, register, value

main code would do
Load I/O address in Z80 register
Load address of length byte in a Z80 register
Call stream_out

Now you see a problem, With no stack at this time calls do not work!
But this is a problem only during boot & no stack
Boot with no stack could use the following

SIO_INITA:
; init channel A
length, register, value, register, value
Return_address
SIO_INITB:
; init channel A
length, register, value, register, value
Return_address

and instead of a RET instruction do a

Ld HL ,(address of return_address data)
JP (HL)

And this address just happens to be in a register. You used the register to access the table of data.

Now some trick code


Call InLine_stream_out
Db length
DS "This it message output."
; More code here the sub will return here


The sub InLine_stream_out
 pops the return address off the stack and uses it as a data pointer to read Length and stream
read length
loop outputting bytea until length = 0
Pushes address back on stack. At this time it should be pointing at address of :more code
RET   : This takes back to running code starting one byte after last stream byte

look at instruction OTIR

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #74 on: November 24, 2017, 09:23:52 AM »
That's what I find fascinating about assembly - it can be streamlined and optimised in ways that almost look like black magic to the uninitiated!  There's some good advice there, C - thanks very much!

My plan is as follows:

1. Sanity-check all connections to the MMU and from MMU to memory.
2. Check that I've got no stray signals from Grant's old ROM (de)select circuitry causing problems.
3. Clarify the voltage reading I'm getting on pin 1 of the LS670.  It should be higher than 4.2V.
4. Edit the ROM assembly to stop execution before the ROM is mapped to just Area 0 (this way I can test to make sure Q4 is actually low in error, rather than low because the Z80 has randomly executed some code and the ROM is not being accessed when I test with my multimeter.)  Can I just stick a HALT at the start of MINIT: to do this?
5. Include some code to see if I can get any text out of the SIO/2 as part of step 3 above. (Thanks for the suggestion, C!)
6. If all the above fails, spend a couple of weeks learning how to do timing charts for the Z80 and work out if the Z80 needs any WAIT states for the MMU to keep up.

 :palm:
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #75 on: November 24, 2017, 11:53:50 AM »

Can think of a couple of problems areas.

With the memory mode you are running the memory in, you need U8:A & U8:B wired like grant's drawing. Pins 3 & 6 connect to ram/rom grant's way.
Pin 3 to ram WR
pin 6 to RAM & ROM OE

All Ram/rom address/data lines go to Z80
Except for A14 and higher.

Did you get the High 16k area of ROM programmed properly?
It should match first 16K except for those bytes in the message.
If not sure
From What I know you were running 16K ROM with reaming RAM until all ram.
If so with only first 16K programmed you could strap A14,A15,A16 low only at ROM
Q4 would still do rom/ram but rom would act like a 16k rom

before step 4 I would

Patch/strap the 670 so it stays in tri-state output mode.
Remove connection to Pin 11Gr and pull high or strap high
does mot matter what Z80 does Q1-Q4 should remain high and connected memory pins high with ROM selected

If this is correct then output of 670 is probably correct.

If not and you have a second ROM, put 00h in all locations.
Z80 will do nop and A0-A13 of memory should count.

A volt meter is not a good way to troubleshoot a running computer.
job for scope.

Can I just stick a HALT at the start of MINIT: to do this? should work

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #76 on: November 25, 2017, 09:21:28 AM »
With the memory mode you are running the memory in, you need U8:A & U8:B wired like grant's drawing. Pins 3 & 6 connect to ram/rom grant's way.
Pin 3 to ram WR
pin 6 to RAM & ROM OE

Yep, that's all in place still.

All Ram/rom address/data lines go to Z80
Except for A14 and higher.

A14 & A15 from the Z80 go straight to the MMU (670).  The Z80's A14 & A15 are now only connected to the rest of the address bus via the MMU.

Did you get the High 16k area of ROM programmed properly?
It should match first 16K except for those bytes in the message.

Yes, I've actually copied the monitor code into all 8 banks of the ROM earlier this evening (00000h, 04000h, 08000h, 0C000h 10000h, 14000h, 18000h and 1C000h) - so whichever ROM bank is selected, the SBC should boot.  It still doesn't, so this tells me that the ROM isn't selected at all by the MMU (which backs up the multimeter reading I took yesterday on Q4 being low.)  When I get more than 5 minutes to work on the issue, I'll get the oscilloscope out so don't worry, I won't be using the multimeter anymore. ;)

So, I've had little time today to look at the issue but I was able to program the ROM with monitor code in each of its 8 banks and try the SBC again.  It still doesn't boot, so this backs up my earlier observation that Q4 was low and thus the MMU wasn't selecting the ROM properly for boot.  I'll take a closer look at the MMU this weekend and check the voltages and signals to the 670.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #77 on: November 25, 2017, 04:49:19 PM »

My first thoughts on last post.
Use a 138 NOW to select the ROM & RAM chips.
So if you connect the address input of 138 to Q4 and can swap connections, could be a quick get computer working step with a better future.
This still has all RAM or ROM and needs 670 to add the other.

You only need one address input to select between the ROM & RAM chips.
And the BIG one, you can swap connections between Y0 & Y1.
AND Know that only one output will be enabled at a time.

Some day I am guessing that you will want to do something and need a memory space to do it in.
You will have two more address lines you can use for future memory expansion.
You will have three inputs you could use to disable memory in future. This is a powerful thing. Take a glance at Mouser 9 different parts you could use to make a 256 byte block of memory special from an additional memory chip and where in Z80 memory controlled by an output port (Logic Comparators 8bit Identity ).

But the really great thing you could directly connect 138 to Z80 for some tests if connection to Q4 fails.

So Test steps
Read complete post and change order for what you see happening.

Looking at Grant's basic code
Looks like it wants ram starting at 16k & has question for top of ram.

So quick question you might know, will it work with just 16k of ram?
Thinking of telling Basic that it has 16k of ram.

If you connect Z80 A14 to 138's address input you can have 16k rom & 16k ram.
You could disconnect Q1-Q4 from memory
With RAM & ROM your interrupt SIO could work.
Should be small change if it does not work.

You could use BASIC output port command to test some of 670 function.
Knowing that GR(pin 11) RA ( pin 5) & RB(pin 4 ) for 670 dip control what happens on Q1-Q4 and nothing else you could jumper these to what you want.
Use basic output port instruction to write to 670 and check Q1-Q4
You could also check the connection that should go to GR

The problems come with connecting 670 to memory.
IT is almost work or die.
If the copies of rom are the same then you could swap rom with out crash.
The question is then did it work?

The way to find this out is make each of the rom copies different in a way that does not crash the Z80.

You could make Power up prompt output the Bank value.
8 copies of your 16k rom with one byte changed.
How you connect output of 670 and the inputs listed above determines what you get.
With original connection of 670 inputs
  Area 0 could switch to even banks
  Area 1 change is a risk of crash
  Area 2 could switch to even banks
  Area 3 could switch to odd banks
  Area 0 & 2 would always be ROM but you can change bank.
  Area 1 & 3 would always be RAM.but not connected for change.
First connect Q1-Q3 only to ROM keeping the 138 connected via A14 to control RAM/ROM
Un-used address inputs to ram strapped to a level.
You could change area 0 & 2 via basic the then peek the changed byte.

When this is working you could add RAM to Q1-Q3
This is the big step. Change area 1 and expect a crash
 You can test area 3 changing ram bank
All software must be correct
You can not swap bank where program is running.
You can not swap bank where stack is located.
You can not swap a bank and mess up interrupts.

when you change connection of 138 from Z80 A14 to Q4
You have 0-7 = RAM, 8-F = ROM
Now you know that basic should not change ROM code.
Break the rule and swap area 0 with a copy of area 9
Use Z80 to copy ROM to a unused block of ram.
You can then swap area 0 with this ram block.
Remember to change that one byte when coping rom.
Check byte after swap.

Think of what you have tested
You have not changed Area 1 and above only works if it stays the same.
You have tested Area 0 of 670
You can test area 2 & 3

You used the Rom BASIC to make changes and test change worked.

Now think about using MMU
You could setup a new table for interrupts in a different area.
When you change the I register You just made new table active.
This could be only a table location change.
Any time you want you can change contents of interrupt table as long as you keep it pointing to good code.

You can move the stack to a new area. With good code you could move back to old stack at proper time if needed.

CP/M3 with proper code you write will do this changing for you.

Even with CP/M2 you can do huge programs & huge data.

Think about your scope or meter
Often you can use even when out of calibration.
You meter is a ratio device. The same scale is showing a ratio. You can use this to check if meter is working.
The scope uses voltage for one ratio and time for other ratio.
A lot of time when using a scope you just care about the shape.
You have things you know what they should be.
Instead of measuring everything compare things.
If you have a logic divider you know output should be about 1/2 input in time.

Think about your Z80, standard test conditions for CMOS version is 4.5v to 5.5v for supply.
Good TTL logic 0 is < 0.8v with a logic 1 > 2.4
Lots of things you can compare with scope.
Most of time you are looking for a difference from something that should be close to same.

USB power shows X, 74LS670 should be close to same
Z80 is close, other chips are close, you have why the difference for any half way working scope.
This works even with changing signals if you have something else to check for comparison.

Old analog volt meters would shake needle some on DC with low frequency noise. Digital gives a slow average.
Scope shows noise and lets you decide that is about correct DC level.
A bad diode or cap shows quickly on scope.
 

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #78 on: November 26, 2017, 11:33:06 PM »
Okay, spent about 15 minutes sanity-checking the wiring and found two howlers where I'd mis-connected a couple of address lines and for some reason had two select lines running from the 138 (one through the OR gate with ~WR and the other direct from ~Y7.)  :palm:

It's working beautifully now, even at 8MHz!!  :-+

I'm able to swap RAM and ROM banks in and out with ease (confirmed using my memory viewing program and writing the bank numbers to the start of the 16K block using POKEs) using the BANK command I created for the monitor (DMI) program - all I need to do now is tweak a couple of CP/M programs that handle returning to the DMI without doing a (very) hard reset (have to power the SBC off until I MMU-ify the appropriate CP/M program that returns me to the DMI) and create the BANK command for CP/M and I've got a 256K computer. :)

Thanks C and Ian.M especially for your assistance. Couldn't have done it without you!   :-+ (On to the PSG now!)
 
The following users thanked this post: Ian.M

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #79 on: November 26, 2017, 11:53:03 PM »

For Z80 you have a CALL instruction
Call instruction puts return address on stack
Sub uses RET instruction
return address gets used

MMU version

Z80 calls bank swap sub whth data, Data = address of sub or address of data

Bank swap sub
pushes return bank address info on stack
swaps the bank
calls the sub
Sub returns to bank swap sub
swaps back to original bank
returns to program.

For data  you need to move it both ways.
The Z80 has a PUSH instruction
You need bank PUSH

Z80 has a POP instruction
You need a bank POP

Keep in mind that sometime a word value or something else like a buffer will be split across two banks.

 
The following users thanked this post: nockieboy

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #80 on: November 27, 2017, 12:44:59 AM »
If you manage to add an extra FLASH chip for ROMdisk, get CP/M Plus running, loading from ROMdisk and layout a nice PCB for it you'll have a really nice 'retro' system.  Consider designing it as a S100 bus CPU card to make it easily expandable.  You'll need bus buffers and probably a programmable wait state generator for accessing S100 bus peripherals, and some of the memory space will need to be mappable to the bus, so you may need to add another '670 to gain some extra address lines EA18-EA21
« Last Edit: November 27, 2017, 12:50:02 AM by Ian.M »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #81 on: November 27, 2017, 01:14:10 AM »
Sorry I forgot the  :-+

Now before you get tooo distracted by other things.

Would be a good GREAT idea to look at your timing.

Is the Z80 working with low time margin when running a 8Mhx?

Could this margin be such that some instructions could be read from memory wrong?


lan.M
  I would not build to S100. Old bus with high dollar cards due to the hack on top of what was previous S100 standard.
Has a lot of good ideas that should be copied.

The Z80 will work on a VME bus. This is a large step up from S100. Built with idea of vector interrupts, many processors, large address space & 8 or 16 bit CPU's.
Should take less chips and just work better.

Would be a good idea to get out your scope and measure things.

For instruction fetch
Trigger on M1

Look at Z80 data sheet that lists times and measure them using your scope.
What you want to know is all at the Z80 chip pins.
For address bus you are looking for a range of when change starts and ends
A range for data bus.
here you have two ranges you can collect Rom/Ram Boot rom / CP/M

Get range of Q1-Q4 of 670

Get values at Rom Ram pins.

Get values for Z80 memory read/write

Get values for Z80 IO read/write.

If you think you have poor scope then record the time base setting.
Think you have an AVR with a crystal get it's time.
A 16mhz crystal should be close to 16mhz. This is a check on scope time base and could be a correction factor for an out of cal scope.

Last circuit I saw for PSC, could have data on bus for too long a time. Would be good to check.
It could be working, but not good long term to have two things driving a signal.



EDIT ADD

The MMU control is output only.
You will need MMU area values  when you try to get back from using or working with a different area.

Software FIX
You have a copy of what was last written to MMU in common memory.
When you start to make a change to a new bank,
  1. push a copy of common memory MMU values on to stack
  2. as you make changes to MMU change common memory MMU values also.
Use the new MMU map

   3. on return from using MMU map
Read old MMU values from stack and update MMU and common memory MMU values

This setup lets you change MMU many times and return back to previous settings.

This is foundation for what could look like magic.
« Last Edit: November 27, 2017, 04:26:56 AM by C »
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #82 on: November 27, 2017, 11:05:17 PM »
EDIT ADD

The MMU control is output only.
You will need MMU area values  when you try to get back from using or working with a different area.

Software FIX
You have a copy of what was last written to MMU in common memory.
When you start to make a change to a new bank,
  1. push a copy of common memory MMU values on to stack
  2. as you make changes to MMU change common memory MMU values also.
Use the new MMU map

   3. on return from using MMU map
Read old MMU values from stack and update MMU and common memory MMU values

This setup lets you change MMU many times and return back to previous settings.

This is foundation for what could look like magic.

Already sorted that before the MMU was functional, C.  :-+  The command I used to change Area/Bank mapping will, if no parameters are passed, show you what the current mappings are:

Code: [Select]
OK
bank
Current memory mapping:

AREA 00 -> BANK 00 (RAM) *LOCKED
AREA 01 -> BANK 01 (RAM) *LOCKED
AREA 02 -> BANK 02 (RAM)
AREA 03 -> BANK 03 (RAM)

RAM: 64KB, ROM: 00KB
OK
bank 02,06
OK
bank 03,0b
OK
bank
Current memory mapping:

AREA 00 -> BANK 00 (RAM) *LOCKED
AREA 01 -> BANK 01 (RAM) *LOCKED
AREA 02 -> BANK 06 (RAM)
AREA 03 -> BANK 0B (ROM)

RAM: 48KB, ROM: 16KB
OK

EDIT:  In case you're wondering (you're probably not) - the *LOCKED comment means that Area is fixed and cannot be changed with the BANK command, so you can't inadvertently crash the system by swapping out the stack and currently-executing code.  Of course, there's nothing stopping you doing it with direct OUT commands, but it's an idiot filter for when I'm not thinking about what I'm doing.  ::)

Code: [Select]
bank 00,0f
Cannot remap locked Areas
OK
« Last Edit: November 27, 2017, 11:09:49 PM by nockieboy »
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #83 on: November 28, 2017, 02:45:23 AM »
Adding hardware read-back of the MMU registers could be done, but the logic cost of doing so is probably prohibitive in a LSI/MSI glue logic build.

Unfortunately the cost in logic to guard the MMU I/O port so it can only be accessed immediately after a specific instruction sequence is also prohibitive, so you'll have to be careful to avoid rogue programs that probe or scan ports etc. but its something that you should consider if you ever add a CPLD or FPGA that has access to the whole data bus, and the signals required to decode all memory and I/O accesses.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #84 on: November 28, 2017, 04:22:29 AM »

Think you are ready to work on CP/M3

For long term
  Think it would best to use CP/M3's relocating assembler.

If you were doing TurboDos I would suggest it's  relocating assembler.
 From memory the source changes were small to none.
Do not remember is source to both works.

There is also M80 that was from microsoft.

All three have linkers that let you put relocatable binary output together to make a working program
L80 is microsoft linker.

For text processing I used wordstar3.3

Some programs/code contained their own reallocators in memory.
The ones I remember used a simple bit table to change the value of a byte.

You assemble code two times with a ORG change of 100H
The binary bytes that are different are the bytes needing to change to move code in steps of 256 bytes.

From memory SID and ZSID did this.

Now that you have a MMU, what other areas do you want to learn?

I am assuming that you now know what would need to be changed if you wanted to use larger memory chips or a larger address space.
 
The following users thanked this post: nockieboy

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #85 on: November 28, 2017, 05:07:05 AM »
Also see https://www.z88dk.org/ for a relatively modern toolchain for Z80 cross-development in assembler and C.
 
The following users thanked this post: nockieboy

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #86 on: November 28, 2017, 05:16:24 AM »

CP/M3 & TurboDos both have a large amount of relocatable code modules that you use to build the system.

If you do not have new code in compatible relocatable code modules the build tools do not work.

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #87 on: November 29, 2017, 03:12:47 AM »
Also see https://www.z88dk.org/ for a relatively modern toolchain for Z80 cross-development in assembler and C.

Thanks Ian - I'm already aware of the site as I found it in previous searches to do with building the SBC.  I haven't had the opportunity to take a long look at the site yet, but if it offers tools that will help with getting CP/M 3 up and running, I will certainly do so!  :-+

Think you are ready to work on CP/M3

For long term
  Think it would best to use CP/M3's relocating assembler.

Yes, I think that's going to be the next project - I'll leave the PSG until CP/M 3 is stable, as the majority of the work to do with getting the PSG running is software-based rather than hardware (although there's still the clock timing issue I have to resolve.)

Some programs/code contained their own reallocators in memory.
The ones I remember used a simple bit table to change the value of a byte.

You assemble code two times with a ORG change of 100H
The binary bytes that are different are the bytes needing to change to move code in steps of 256 bytes.

From memory SID and ZSID did this.

Now that you have a MMU, what other areas do you want to learn?

Well, I'd like to get CP/M 3 up and running!  ;D  Not sure where to start with it, really, as CP/M 2.2 was provided ready-configured on Grant Searle's website, so there was nothing I had to do to get it working from the start.  I've added a few tweaks to CBIOS since then, but nothing too complicated and only relating to varying the baud rate of the SIO depending on the system clock speed and getting the MMU up and running.

I'm going to have to sit down with the CP/M 3 System Guide I think and see what questions arise from reading that.

I am assuming that you now know what would need to be changed if you wanted to use larger memory chips or a larger address space.

I think so, yes.  If I start thinking about upgrading the physical memory space, I'll be sure to check in here first to check my designs out with you guys though. :)
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #88 on: November 29, 2017, 03:44:35 AM »
Take a Z80 emulator that supports banked memory and, ignoring any existing CP/M, port CP/M Plus to it.    Here's a configurable Z80 system emulator: https://k1.spdns.de/Develop/Projects/Z80%20EMUF/ that appears to be recently maintained, and from a quick skim it looks like you can code an exact emulation of your Z80 system using it.

If you want a more advanced MMU in the future, I'd suggest the one I initially pointed you to using '486 era cache RAM for the address translation.  These very fast small 5V SRAM chips are getting rarer and harder to find, so it would be worth acquiring a few sooner rather than later.
 
The following users thanked this post: nockieboy

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #89 on: November 29, 2017, 03:59:49 AM »

CP/M 3 is just an expanded CBIOS

Think that you will find that most grant's CBIOS will work for same CP/M3 CBIOS Function.

You are just adding some new functions fo most part.

There were some code cleanup's done.
From memory
CP/M2.2 CBIOS  had most sector blocking code in CBIOS, the putting/getting the 128 byte blocks ito/from to large block for drive.
CP/M3 now does more work making user created CBIOS simpler.

Just start with Grant's CBIOS for 2.2.
Check each function in Grants for a change on how it is called and what output is wanted.

Add the new function calls.
Think there are examples where you have dummy functions for CP/M3 running in 64k or less memory.

Do this step first. Result should be a CP/M2.2 program that changes OS from 2.2 to 3.0.
Should see little change, A CP/M2.2 program most times see no change. 
Disk format should not change.

Not worth time jumping to emulator where you have a working CP/M2.2 CBIOS to start from.
 
The following users thanked this post: nockieboy

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #90 on: November 29, 2017, 04:16:13 AM »
Jumping to emulation gives you debugging capabilities that aren't possible on a real Z80 system without FPGA assistance, .   I did a paper study way way back in the '80s before FPGAs and cheap MCUs were a thing of what it would take to build an invisible Z80 hardware debugger - no resources used on the target system, and CPU state restored as fully as possible on a normal Z80 chip before resuming execution,  and it was going to be a real bear to build and implement.   

Also, if you want to share your project, a working emulator will go a long way towards popularising it . . . . .
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #91 on: November 29, 2017, 05:14:37 AM »


Sorry lan.M

Did not say last very good
Depending on emulator capability nockieboy having access to one would be in good to great range.

For CP/M3
Here he states that he has software that he used to change the MMU and Check it's function.

Only step left is to make parts of this a CP/M3 function.
Do not think nockieboy will have much trouble with this step.

Remaining steps are also small
Most CBIOS functions will be un-changed.

Un-like CP/M2.2, CP/M3 is a CP/M2.2 program.

The old load cpm2.2 from boot track has changed to a loader that then loads the OS as a OS file and runs it.

You can have many different versions of CP/M3 on the boot disk and a change is just running a program.

Run program A to get CP/M3 for non-banked.
Run program B to get CP/M3 for banked.
A rename can change which starts at boot.

The capability to quickly build a new version is why you want to use CP/M3 tools.
A linker input change could be all that is needed to create the wanted version.
Modular Assembly code.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #92 on: December 05, 2017, 01:38:57 AM »
Okay, I'm going to just throw this out there with an acceptance that 'you told me so' previously....  ;)

Now that I'm working on getting CP/M 3 running on my SBC, I've realised that 128K SRAM isn't a whole lot - it only allows CP/M 3 to have a maximum of three banks effectively, if I allow 32KB for each bank rather than 48KB - and only two banks if I use 48KB each.

So I'm considering replacing my 128KB SRAM with a 512KB version.  This (with the 128KB EEPROM) would take the memory up to 640KB - and as someone once famously said, "640KB ought to be enough for anybody." :-DD

There's a big hurdle to jump first though - namely that my current 128KB SRAM is embedded amongst address and data wires on the breadboard.  So I might leave the physical upgrade until I get my SBC onto PCB.

But thinking ahead, I'll need to upgrade my current MMU to allow for another two address lines (EA18 & EA19.)  This can easily be done with the addition of another 74LS670 chip, but what would be the best way to wire it in to the existing MMU circuit?  I presume EA17, the existing ~RAM/ROM select line, would become the ~GR input for the second 670 and I'd remove the inverter to place it on EA19 coming out of the second 670 and going to ROM?
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #93 on: December 05, 2017, 02:39:10 AM »
Nope. 
Its read mode input connections (RA RB, /ER) go in parallel with the existing one, and its outputs Q1:Q4 become EA18:EA21 for a 4MB address space.

Then you have to sort out its write mode inputs so you can load a page table.
Currently you are using a one address write only port with two bits in the byte for '670 addressing.  The way forward is to move the existing and the new '670 write addressing (WA,WB) to Z80 A0,A1 and use four I/O addresses.  Then you can hook the new '670's D1:D4 to Z80 D4:D7, so the low nibble gets stored in the old '670 and the high nibble in the new '670.   You then have to sort out the BOOT mode disable signal - it was a port bit, but the easiest thing to do now would be to make any write to that port block leave BOOT mode.   The first value written would need to map the boot block at the current execution page so the bootup code doesn't crash.  Then you can map the other three pages as required, and finally transfer execution out of page 0 and remap page 0.    It wouldn't be possible to return to BOOT mode for a soft Reset, but you could fake it by mapping the boot block to all the pages and jumping to address 0.

It gets a lot easier to page efficiently if your MMU page size is a lot smaller (4KB seems optimum, giving a 1MB address map) and it can swap between preloaded page tables with a single OUT() instruction.   As I mentioned in your old topic, a 486 era fast cache SRAM  can be used to do that.  Up to 256 page tables could be preloaded, with separate entries for read and write mapping, which allows write protection, and also easy copying of ROM to RAM.  When you don't want that fine grained paging, simply create page tables that swap between 16K blocks.

I'd have to look at the details, but I believe that would permit a CP/M Plus or MPM system to have nearly 60K of TPA!
 

Online glarsson

  • Regular Contributor
  • *
  • Posts: 151
  • Country: se
Re: Z80 memory banking for 128K - MMU design
« Reply #94 on: December 05, 2017, 02:57:59 AM »
I'd have to look at the details, but I believe that would permit a CP/M Plus or MPM system to have nearly 60K of TPA!
You do not need a 4k page size to get 60k of TPA. My CP/M3 system I built in the early eighties used 32k page size with 62k TPA.
Never looked closer at MP/M, but I expect a small page size to be important when combining multiple users and large TPA.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #95 on: December 05, 2017, 06:21:44 AM »
Note first post had error in table below.

Quote
But thinking ahead, I'll need to upgrade my current MMU to allow for another two address lines (EA18 & EA19.)  This can easily be done with the addition of another 74LS670 chip, but what would be the best way to wire it in to the existing MMU circuit?  I presume EA17, the existing ~RAM/ROM select line, would become the ~GR input for the second 670 and I'd remove the inverter to place it on EA19 coming out of the second 670 and going to ROM?

Think of what you are saying here.
Existing MMU always has some memory enabled for a memory cycle. The CS enable is just by the address lines.
The current MMU is 4 16k areas of 256K
Using Q4 of 670#1 to control -GR of 670#2
670#1 16k area 0
670#1 16k area 1
670#1 16k area 2 670#2 16k area 2   <-( left this out on first post )
670#1 16k area 3 670#2 16k area 3

OR
670#1 16k area 0
670#1 16k area 1
670#1 16k area 2 670#2 16k area 2
670#1 16k area 3 670#2 16k area 3   <-( left this out on first post )

With extra I/O input to 670#2
670#2 16k area 0 could change to 670#2 16k area 2
or
670#2 16k area 1 could change to 670#2 16k area 3

I would say this is a big fail.

You only have two address inputs from Z80 to use to select expanded memory. Each bit added to output of MMU doubles the memory size you can select a 16k area from.

========
You always need to think of big picture.
Look at this from other way, not as how many banks CP/M can use but use of your memory.
With 16k banks, 4 are used by CP/M user program

So for big picture, your problem is lack of banks in expanded memory.
A second problem is no space to put more banks in Z80 memory.

First question should be how many areas of Z80 memory can CP/M manage.
Remember that CP/M can use two modes.
Z80 does the work or DMA does the work.
DMA here can be something you write and can use more memory areas then CP/M.

For just one area managed by CP/M
CP/M will move data to common memory and then change banks and move data from common memory to new area. 
DMA will be Move data at this address with a size of  in bank X to
Bank Y at this address.

Need to remember that data could be in two source banks or detestation banks.
CP/M can not force a program to put the Disk I/O block all in one memory area.

With 16k banks, CP/M should know that only three can be changed and still have a common memory ares.

A CP/M program works with blocks of 128 bytes or less
CP/M storage interface can have larger sizes of blocks.
CPM will try to have all of a data block fit in one swapped area.

So two main use cases
Move a small block of data to/from user space.
Move a larger block of data to/from storage.

A large block to/from user space becomes a small block move of many blocks.

Ok time to think ahead and also do what you want.

From CP/M view,
two areas allows direct copy between areas.
Larger areas could allow CP/M to manage a larger total address space.
Areas that are outside of CP/M managed area can be storage
managed by your programming.

So think about this
Adding second 670 can give 4096k total expanded memory.

More logic will be needed for a smaller block size when using the 670's





First step could be for your current memory to act like normal memory.
To do this put a 138 in place of inverter chip select.
Before MMU you just jumper-ed UN-Used address lines to a level.
You now have a memory chip that is half RAM and half ROM.
By using A 138 to decode chip select to memory chips you could have 7 ram & one ROM of same size.
Do not use messy logic to decode memory.

Use a 138 to decode memory for each size of memory!!

You need more address lines to address more memory. Best use of added 670 is to add address lines so that each 16k area is from a larger address space.


look at how you are building now.

Putting memory on breadboard takes a lot of space and a lot of wries that can get disconnected. Most of the wires are daisy chained.
1. Look at having many 32 pin dip sockets you can plug your memory into.
    For max flexibility only a few pins need to be special and not connected to daisy chain.
    You need a  0.05 bus off wires ( a ribbon cable is 0.05). Three ribbon cable connectors could hold two dip sockets. Look at this to get some ideas. And you can have two more dips on other side of ribbon cable.
 
   On a board with solder pads this is a four hole bridge of  wire, top dip, bottom dip, wire , then a space and again for other side of top dip..

« Last Edit: December 05, 2017, 08:07:56 AM by C »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #96 on: December 05, 2017, 08:11:19 AM »
CP/M PlusTM
(CP/M Version 3.0)
Operating System
System Guide
http://www.cpm.z80.de/manuals/cpm3-sys.pdf

Think the following is correct

On page 11 it states banked system A min of 2 and a max of 16 of what CP?M calls a bank

Looking at Figure 1-2 on page 5

If you had Bank 0 split at 32k
Lower part could switch between 16 32k areas (512k)
and you need 32k for upper half.
A 512k Ram chip would let you have 15 CP/M banks.

Matching your MMU
Upper half of 16k for bank 0
lower could be 16 48K blocks (768k)
A 512k Ram chip would let you have 10 48k CP/M Blanks
16k for common and 16K unused by CP/M
or
Above 15 CP/M banks and 32k common.

Note the max for CP/M
32k switch area is  512k + 32k common
48K switch area is 768K +16K common

Above these limits can be memory managed by your code.
It would be easy to have Ram or Rom disks in memory.

If you look at figure 1-7 page 10

That could be a ROM disk drive
Your Z80 power-up boot could exist above Track M

Think of how little you need to write code to do this.

To power-up boot Z80 you need top 16k as ROM for power-up boot code.
Current code is
copy "Cold Boot Loader" from CF card (disk drive)
So a switch from CF to Expanded memory ROM choice on CP/M boot.

To Treat Some ROM as a disk drive
Table for CP/M to know structure of drive.
Code for CP/M to use to read/write to drive.

As Disk drive CP/M has tools to write/read "Cold Boot Loader"
After formating can manage all remaining space.
Drive size = ROM size - 16k(power-up boot)


 
 
The following users thanked this post: Ian.M

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #97 on: December 05, 2017, 09:29:37 AM »
Quote from: page 11
A minimum of two and up to sixteen banks of memory with the top
4K-32K in common memory. Bank 1 must have contiguous memory
from address 0000H to the base of common memory.

If your MMU permits fast paging in 4K blocks, (giving an address space of  1MB), a 16 x 60KB CP/M bank system is possible using a total of 964KB of RAM.   That's two 512KB (4Mbit) RAM chips, leaving 60K unused.   Add a latched port bit somewhere to swap the top one with a 512KB FLASH chip, that is initially selected on Reset, and you can use it for the bootstrap and also as a ROMDISK. Obviously you need to double-buffer if you need to transfer data from FLASH into the top RAM chip, but that isn't too much of a PITA.   About 500KB should be fine for holding CP/M Plus System and Utilities.

If you hook up the /WR signal, you can also write to the FLASH, but I'd make that manually switchable to avoid rogue code smashing your bootstrap or system disk.  With an appropriate utility (to run from RAM), that would allow re-flashing your system in-situ. 

The quiescent current for two 4Mbit SRAMs is low enough that you could make them battery backed - with some logic to force Z80 /Reset low if the unregulated supply drops, that could give you a non-volatile RAM disk.   Generate a NMI instead of a Reset, and add a handler for it and you could do suspend/resume.
« Last Edit: December 05, 2017, 09:32:33 AM by Ian.M »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #98 on: December 05, 2017, 02:29:57 PM »


If your MMU permits fast paging in 4K blocks, (giving an address space of  1MB), a 16 x 60KB CP/M bank system is possible using a total of 964KB of RAM.   That's two 512KB (4Mbit) RAM chips, leaving 60K unused.

With fast static cache ram you could do this for a MMU.

Not possible using two 670 chips with out a lot of logic
Simple is 4 16k banks for Z80 using one address space.
With 8 bit output from the two 670's you could have 4MB total expanded space.
Or waste some expanded address space and use some 670 bits for extra control.

    CP/M                           MMU           
Block   managed              block
size     memory space      size
32K          512K                  32K
48K          768K                   16k
56K           896K                    8k
60K           960K                    4k

Need to remember that the floppy disk drives that most systems has wore small by todays standards.

If there was a standard floppy disk for CP/M it was a
8" single side, single density, 128 byte sector, 26 sector per track ,77 track drive
This is about 250k when formated
Double density increased this to 500K
Dual side to about 1M

A lot of computers used 5 1/2" drives 100k, 200k, 400k

CP/M3 can speed up a CF drive some.
A fast drive for CP/M is a ram disk.

So a small MMU block size sounds great but gains less with each step smaller for CP/M.

Using parts of the 4M space for RAM/ROM disks us a gain.
Using some of the 4M space to access new hardware or other systems is a gain.

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #99 on: December 07, 2017, 07:04:47 PM »
If you hook up the /WR signal, you can also write to the FLASH, but I'd make that manually switchable to avoid rogue code smashing your bootstrap or system disk.  With an appropriate utility (to run from RAM), that would allow re-flashing your system in-situ.

I think this has been mentioned before - either in this discussion or one of my other related posts - and probably by yourself Ian.M, so apologies if my memory is failing me.  Although my current system has the FLASH ROM sitting in a ZIF socket on the motherboard, it's not without its own fiddly complications as the ZIF doesn't always quite sit properly and has to be pushed down to re-seat it etc. after a number of programming cycles.

I have every intention of putting this SBC onto a PCB in due course - either stripboard or (if costs allow) something more permanent, like a professionally-manufactured PCB - and whilst I don't mind having a ZIF socket on the PCB, in-circuit programming of the ROM would be a very nice feature to have!   :-+

Is there much involved in doing it?  I'm guessing that a switch would control the ROM's ~WR, after putting the Z80 into tri-state with a ~BUSREQ (not necessarily in that order, of course - I have an Atmega328 on the board which could run this sequence) and allowing the 328 DMA access to the ROM?

I'll start researching this idea I think.  I'm up to my eyes in CP/M 3 BIOS at the moment, so a hardware challenge will be a welcome distraction!  :-+
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #100 on: December 07, 2017, 07:52:04 PM »
Yes, if you can grab the bus, you can do it that way, but a much simpler approach is for the Z80 to run from RAM, bootstrapped by the ATmega328.  You need some way of getting code into RAM - but that's just a matter of disconnecting (or inhibiting) /RD to the memory, releasing /Reset + a hardware circuit to assert /WAIT every /MREQ + /RD from the Z80, and signal the ATmega328 so it can stuff a byte on the bus then release /WAIT.   

It would send opcodes and data bytes to configure the MMU, and load DE with the desired address to copy to in RAM then stream LDI instructions to copy the desired code into RAM - probably a simple monitor program.  For each LDI the write to (DE) taking effect but the read from (HL) actually being supplied by the ATmega328, without reference to HL on the address bus, so one payload byte is transferred for every two opcode bytes.  Finally it stuffs a jump instruction and re-enables /RD from memory and disables the /WAIT circuit. 

At that point the Z80 is running the monitor, and a PC application can use it to bootload the system with *ANYTHING* from a simple IntelHEX download + FLASH write utility, up to a full CP/M Plus system running from RAMdisk.  The PC application can be just about any off-the-shelf terminal program that supports paced sending of text files.
« Last Edit: December 07, 2017, 08:11:46 PM by Ian.M »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #101 on: December 07, 2017, 08:05:35 PM »
Your flash rom has a software protect feature to prevent accidental writes.

You should be able to just connect your existing /WR that goes to RAM to your Rom chip with no problems.

You would gain the most power by having the Z80 able to write the Flash Rom.

Now as you are working on CP/M3 BIOS keep in mind a few things.

In addition to the CP/M3 config that will build your CP/M3 system, some systems also have/had a special program that could change some data fields in the working BIOS.
For example, you might boot from one CP/M drive and after running some code or CP/M programs, change the CP/M drive map.

Keep in mind that CP/M has a program that can write to boot/system area.

IF you add the proper drive tables you could have RAM or ROM disks.
You could use CP/M format to put directory structure in place. Then just copy files to new drive.

The only special thing you will need to do after getting capability to FLASH Rom write is a special program to put the power up boot in the highest 16k area.  Make your CP/M ROM Drive 16k smaller then top of ROM.

With some good code even CP/M2 can use a RAM or ROM drive.

With CP/M3 capability to run a program on CP/M2 and change to CP/M3 you have a great test environment.

Build a NON-Banked version of CP/M3
Use this to build two more CP/M3 versions
CP/M3 with ROM and/or RAM disk drives.
Banked CP/M3
Banked CP/M3 with ROM and/or RAM disk drives.

For future keep in mind that a CP/M disk drive could be a file or array of blocks on PC or something.

You will gain more by having Z80 write to Flash Rom then  Atmega328 writing to Flash Rom

lan.M's post is for
NO CFcard drive in system that is working.
NO Rom in system that is working.


 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #102 on: December 07, 2017, 11:37:07 PM »
Yeah, I like the idea of having some sort of storage media like Compact Flash (or SD card via an SPI interface) rather than using the 328 to completely bootstrap the Z80 with no ROM.  Would be great if I could just flick a switch, put the SBC into 'ROM programming'-mode, and stream a new monitor HEX file from the terminal or via the 328 and its USB connection.

All I'd need to do is hold the Z80 in reset, or tri-state its address/data buses with a ~BUSREQ and let the 328 do the rest.  The only problem with that system is that currently, the 328 is only connected to the Z80 system via a serial interface to the SIO.  I'd need a bigger micro-controller if I want it to be able to take over the address and data buses...
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #103 on: December 08, 2017, 12:07:09 AM »
Not really.  Just add a 74HC595 hooked up to the ATmega328 SPI pins.  Its output is tristateable so it can go direct to the data bus, then you only need a few more I/O pins for the bus stuffing logic.  By stuffing Z80 commands (+ data) you avoid the need to interface to the address bus + can get the CPU internal state if you add a 74HC165 to read the data bus.  You can even use it to implement a hardware debugger though it will need two bytes of stack in RAM - add hardware to decode a M1 cycle at address 0x0066 to detect a NMI has occurred, then your ATmega328 takes over and stuffs instructions, the first being PUSH AF with the memory disabled to read out the Accumulator  and flags from the bus, then you can push the other register pairs and start shuffling stuff internally to get a full readout.  Once you've got the CPU state without affecting RAM (other than the address stacked on NMI entry) you can stuff instructions to manipulate memory or I/O, and disable the stuffer for just the right number of /MREQ or /IORQ cycles for the instruction just stuffed to access the memory or peripherals.   To resume normal execution, you stuff POP instructions + the previous register contents to restore the CPU state then stuff a RETN. and disable the stuffer.   To implement single stepping is easy - the next /M1 after debugger exit must trigger a NMI.  To implement breakpoints is harder - the easiest option for RAM only breakpoints is to put DI + JP 0x0066 at one of the RST vectors, then that RST instruction can be used as a software breakpoint.
« Last Edit: December 08, 2017, 12:20:42 AM by Ian.M »
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #104 on: December 08, 2017, 06:39:35 AM »
Ouch.. that sounds waaay beyond my feeble digital electronics and assembly comprehension and skills...  :o

Okay, well maybe I should just focus on getting CP/M 3 up and running for the moment.  I'm getting sidetracked by interesting ideas that are ballooning into quite complex concepts (at least to my inexperienced mind!)  ::)
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #105 on: December 08, 2017, 07:24:07 AM »

Why not do the easy thing?

You have CP/M running.

There are many programs that allowed one CP/M computer to talk to another computer and transfer files


file transfer protocols
Kermit
XMODEM,YMODEM, ZMODEM

Some of these are built in to a PC terminal program
TeraTerm is one of many for PC side


 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #106 on: December 08, 2017, 08:37:12 AM »
It should be easy enough to understand.   Think about it some more and consider what it would take to feed the Z80 a known sequence of  opcodes and data bytes in place of what would normally come from the external memories.  If you want to use a smaller ATmega, it needs a couple of shift registers so it can do the Z80 data bus interface via SPI, to save pins,  it doesn't hook up to the address bus but does need several control signals and some of them have to be intercepted - do that with analog switches to minimise the propagation delay when the hardware bootstrap/debugger is not in control - and some glue logic to handle some control signals that are too fast for the Atmega to handle in code.

If you want a full debugger, it has to know when the CPU is about to start a new instruction so it can jump in and take over. Its a PITA intercepting NMI by decoding a M1 fetch from 0x0066 as that's 16 address lines, 12 low and 4 high that have to be decoded, but that's the cost you have to pay because you don't have access to an ICE bondout version of the Z80 CPU if you want to do it in hardware.  The alternative is for the ATmega to assert /Wait, sniff the data bus for the byte on it then release /Wait till the next /M1 cycle (needs some logic to do that autonomously), while it runs the stream of /M1 bytes received through a state machine that recognises ALL the z80 multi-byte opcode prefixes.  When it reaches a M1 fetch that hasn't been modified by a prefix, it can take over from the memory and substitute its own data on the bus to take control of the CPU.
 

Offline jgh

  • Newbie
  • Posts: 1
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #107 on: December 08, 2017, 09:52:37 AM »
Is it too late to chuck this in the mix?

(I only stumbled across this forum yesterday)
 
The following users thanked this post: nockieboy

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #108 on: December 09, 2017, 02:15:40 AM »
Is it too late to chuck this in the mix?

(I only stumbled across this forum yesterday)

Wow - that's certainly an impressive spec for 3 chips and some glue logic!  Might have to give that one a try at some point in the future when I get hold of some larger memory chips!  Also an interesting web site with some fascinating information on it. :)
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #109 on: December 09, 2017, 02:33:46 AM »
Why not do the easy thing?

You have CP/M running.

There are many programs that allowed one CP/M computer to talk to another computer and transfer files

file transfer protocols
Kermit
XMODEM,YMODEM, ZMODEM

Some of these are built in to a PC terminal program
TeraTerm is one of many for PC side

I'd like to keep the SBC as simple and standalone as possible - I eventually plan to add a keyboard interface and CRT driver so it is complete standlone, so I won't be connecting it to a PC except for debugging/software updates, perhaps.

EDIT:

Actually C, I think I follow you - you mean transfer the data into CP/M in the same way I currently do with files from my PC (as a pasted data stream).  Once in CP/M, I can just write a program to do exactly what I've outlined below in my response to Ian.M's post and write the data to the ROM with just a simple hardware change to allow me to set the ROM for write access...?

It should be easy enough to understand.   Think about it some more and consider what it would take to feed the Z80 a known sequence of  opcodes and data bytes in place of what would normally come from the external memories.  If you want to use a smaller ATmega, it needs a couple of shift registers so it can do the Z80 data bus interface via SPI, to save pins,  it doesn't hook up to the address bus but does need several control signals and some of them have to be intercepted - do that with analog switches to minimise the propagation delay when the hardware bootstrap/debugger is not in control - and some glue logic to handle some control signals that are too fast for the Atmega to handle in code.

I understand the principle of injecting op codes and data onto the data bus to make the Z80 do the heavy lifting and store the ROM hex file in RAM before writing (or flashing it) to the ROM, but in practice it just seems like a huge task.  So I'd be looking to intercept a 'POP DE' op code from the Z80, for example, and injecting (e.g.) the first 2 bytes of the new ROM hex file onto the data bus, so the Z80 thinks it's getting DE off the stack but is actually getting two bytes of data from the micro-controller. 

The program running on the Z80 would then take the contents of the DE registers and LD it to a RAM address in HL.  INC HL, rinse and repeat until the ROM hex file is fully transferred from the micro-controller to RAM.  Then the program running on the Z80 could just write the data to ROM with an IO select via a flip flop to pull the ROM's ~WR line low and LDIR it across, resetting the flip flop (and making the ROM read-only again) when its done?

The issue is that for such a simple concept, it requires a detailed knowledge of the Z80 architecture in terms of control signals and timings - one I don't believe I have at the moment, not to mention hijacking the data bus.  I'll admit to finding the idea highly elegant but somewhat scary and fraught with problems.
« Last Edit: December 09, 2017, 02:37:19 AM by nockieboy »
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #110 on: December 09, 2017, 03:49:35 AM »
My explanation of how you can make the ATmega bootstrap the Z80 is really not that tricky, and doesn't need a deep knowledge of the bus timings - or at least no more so than you need to build a Z80 system that's more complex than a minimal one in the first place.   The idea of a zero CPU resources hardware debugger is however a lot more complex so I quite understand your reluctance to start down that road at thios stage.   Its something you could retrofit later by adding a daughterboard carrying the hardware bootstrap/debugger between the Z80 and its socket.   Adding mounting holes to permit such a daughterboard to be secured with PCB standoffs would future-proof your design.

However if you aten't going to have a hardware bootstrap of any sort, then you are up s--t creek if the boot block in the FLASH chip gets corrupted.  If you want to avoid having to pull the FLASH chip to put in your programmer, I strongly recommend writing a monitor ROM that can cold-boot the machine, and can also receive data in IntelHEX format and store it to RAM.  Burn it to EPROM and provide a socket for it on your memory board. You'll also need a SPDT switch to select between routing the ROM chip select to the FLASH or the EPROM, while the non-selected one is held inactive by a pullup on its /CS pin.   

Then if you brick the FLASH bootblock, you can switch to the monitor ROM, restart anduse it to load an IntelHEX downloader + FLASH writer utility into RAM and run it, then flip the switch back to select the FLASH before sending it the FLASH image to be programmed.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #111 on: December 09, 2017, 05:19:37 AM »
My explanation of how you can make the ATmega bootstrap the Z80 is really not that tricky, and doesn't need a deep knowledge of the bus timings - or at least no more so than you need to build a Z80 system that's more complex than a minimal one in the first place.   The idea of a zero CPU resources hardware debugger is however a lot more complex so I quite understand your reluctance to start down that road at thios stage.   Its something you could retrofit later by adding a daughterboard carrying the hardware bootstrap/debugger between the Z80 and its socket.   Adding mounting holes to permit such a daughterboard to be secured with PCB standoffs would future-proof your design.

Yeah, I see the wisdom in adding daughterboard mounting holes to the motherboard - you never know what you might want to add in future to the processor socket.

However if you aten't going to have a hardware bootstrap of any sort, then you are up s--t creek if the boot block in the FLASH chip gets corrupted.

Ah - hadn't thought of that... the random nasty power-outages mid-way through writing the new boot block etc.

If you want to avoid having to pull the FLASH chip to put in your programmer, I strongly recommend writing a monitor ROM that can cold-boot the machine, and can also receive data in IntelHEX format and store it to RAM.  Burn it to EPROM and provide a socket for it on your memory board. You'll also need a SPDT switch to select between routing the ROM chip select to the FLASH or the EPROM, while the non-selected one is held inactive by a pullup on its /CS pin.   

Then if you brick the FLASH bootblock, you can switch to the monitor ROM, restart anduse it to load an IntelHEX downloader + FLASH writer utility into RAM and run it, then flip the switch back to select the FLASH before sending it the FLASH image to be programmed.

Yeah it's an added expense, but a necessary one I suppose if I'm going to go the route of being able to program the FLASH in-circuit.  Stupid question time - could the FLASH still be written to (to fix the previous corrupt boot block) if its ~CS pin is held high, I wonder?  I suppose it wouldn't be a problem if it couldn't be - I could just copy the necessary program to RAM from the backup ROM and switch it out again, making the FLASH ROM active and then updating it with the new boot code..
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #112 on: December 09, 2017, 06:48:44 AM »
If you think ahead some things get easer.

You have a MMU that can access a large area of memory.

You could have a dip switch between the Flash Rom's WR pin and system, a hardware write protect.

By using a 138 to decode which chip, you could have many flash roms in the system. You can then change which is used for power-up boot by changing which connection of 138 is used for CS.

This is keeping it simple.


 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #113 on: December 09, 2017, 08:38:37 AM »
nockieboy

Think for a bit of starting over or someone else starting to make a copy of what you have.
Trying to use Grant's design has caused you all kinds of problems.
Some comes from using small often costly memory.
As you know now, the cost of new 512k byte memory is cheap.
It is not that hard to connect an address line high or low on a breadboard.
You can use a DIP switch to do this and be able to change it just by changing the switch.

So Grant's design using a larger Rom could have had many things in the rom at a change of a switch.
You could have played with many different rom based z80 systems with just a switch settings change.
One switch setting could be CP/M with ROM & RAM disks.
The needed CP/M programs could have been put on ROM when the rom was created.

Grant went to some work to make a crippled system that is hard to upgrade

When basic system was running, a 273 could have been added to reduce the need to change dip switch settings.

A 374 could have been added to read a dip switch.
  This can add many different modes for system software. One of my systems uses a dip switch to select what drive to boot for system. This system could boot from 8, 5 1/4 | 3.5 disk drives as well as SCSI and network, a nice important switch.

Your MMU then becomes a simple upgrade.
When you added MMU to system, you would just remove some connections from dip switch or 273 and connect to MMU outputs.

In addition to the 273 above changing address lines of Memory chips, it or a second 273 could give you a status output on LED's. Makes testing a lot easer.

Now think of what the above is
A working CP/M system with RAM & ROM disks;
A CP/M program that can send or receive HEX files via console would let you transfer data to/from PC.
Data could be to/from ROM or CP/M files.

A terminal program on PC that knows a file transfer protocol could then be used to transfer files, removing need to convert to HEX on PC.

The un used console port can then be used.
 With a working CP/M system, there exists many programs to cure problems.
A. It was not uncommon to use console port to send/receive programs or data files.
B. It was not uncommon to use a second port to connect to a different system and send/receive programs or data files.

So to summarize
With a working computer, it is easer to get a second computer running.
It can be easy to get a second copy of a computer running with just a little planning ahead.

ONE is a bad number. 
For Z80 having a switch or jumper change to have a second choice for power-up book makes things easer. It is not hard to have two flash roms in the system and keep one write protected with hardware.
Simple would be flash rom's WR pulled high with a resistor & dip switch to connect system WR for each flash rom chip

With Z80 able to read/write Flash Rom it is not hard to have an image stored on PC.
Keep in mind that some things are just easer to have Z80 do the job then the PC.

You are working on CP/M BIOS. One small function is write sector or block. You will be reading/writing blocks of ram. Small change to have a Ram disk. An it's a second small change to have a ROM disk.
You can have CP/M use part of chip and have your bios capable of writing any area of chip.
 
When you can read/write blocks of a rom/ram you can then use CP/M format command to create a working disk.

With good foundation steps it becomes easer to expand.
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #114 on: December 09, 2017, 09:24:22 AM »
You are working on CP/M BIOS. One small function is write sector or block. You will be reading/writing blocks of ram. Small change to have a Ram disk. An it's a second small change to have a ROM disk.
You can have CP/M use part of chip and have your bios capable of writing any area of chip.
 
When you can read/write blocks of a rom/ram you can then use CP/M format command to create a working disk.

With good foundation steps it becomes easer to expand.

That's the one thing I haven't had any time to look at yet.  At the moment, I have absolutely *no* idea whatsoever how CP/M handles reading/writing to disk.  I'm going to have a go at writing some routines to handle programming sectors of the FLASH ROM first as a step towards getting In-Circuit Programming of the ROM up and running. 

Once that's working and I've got CP/M 3 up and running, I can start looking at getting it working with RAM/ROM disks.  The CP/M 3 setup is stalling at the moment as I'm having difficulty working out exactly what I need to do with the CP/M 2.2 BIOS to get it working for CP/M 3, but hopefully it won't take me too long to work it out.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #115 on: December 09, 2017, 10:44:58 AM »
Break it down into simple steps.

CP/M3 has some tools to make this easer. You should use them as they can create some of the data structures that CP/M3 needs an uses.
Step one is to modify your current CP/M2 BIOS code to work with CP/M3 tools and code.
Your source should assembly properly using CP/M3's relocating assembler.
When you have this, modify your BIOS source to be compatible with CP/M3's changes.
When you have this working you have a non-banked CP/M3 system.
This is a good point to test and get working RAM & ROM disks in banked memory.
When you have this working then add bank control to CP/M3
Now you can work on modifying your BIOS to work banked.

=====

Your current CP/M system is just using 64k of RAM
You know your Z80 can read and write RAM.
Simple CP/M wants to read/write 128 byte blocks on storage
Start with a 16K ram disk for your CPM.
Ram disk = 16K total with 128 byte blocks or sectors.

Your CP/M programs will end up in your BIOS at top of Z80's 64k memory.
Your code will need to
1. move data to/from a buffer in high memory BIOS.
     Source or Destination will be in current 64K memory.
     The other will be storage, the ram drive.
     so if write Move source ram to buffer
     bank swap
     if write then move buffer to RAM disk sector.   
     if read then move from Ram disk sector to buffer.
     bank swap back
     if read then move buffer to ram.
CP.M data structures tells your code all it needs to know.

A sector is 128 bytes
Read/write
where in Z80 64k memory for 128 byte block
what sector, track, drive.
If you pick good numbers your code gets easer.
Using 128 sectors a track  lets you use track value to select what bank of 16k
This is fine if you do not need to put os system before the directory on disk.
Best to use a power of 2 for sectors per track.
Using 64 sectors per track will put one bit in track value that is not needed for bank select. So each power of 2 smaller tracks per sector value is from 128 adds a bit not needed for bank select.

With raw read/write, CP/M's format code turns it into a CP/M disk drive.
CP/M's put system turns it into a system disk

When you get this working, expand drive to have more then one bank used.

When you get to this point, a swap from ram to rom gives you a read from rom but no CP/M directory.
Adding the Flash Rom's software write protect code for writes then gives you a working disk stored on Flash Rom.

Simple steps that you can code to test for proper operation.

« Last Edit: December 09, 2017, 11:04:37 AM by C »
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #116 on: December 09, 2017, 10:15:11 PM »
Okay, quick question regarding the hardware ROM write enable - will this work?



The idea is that the ~WE pin is held high, unless the switch is closed when the ~WE is pulled low and the warning LED illuminates.  My electronics skills aren't great, so I thought I'd just check to make sure this would work as intended?
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 5750
Re: Z80 memory banking for 128K - MMU design
« Reply #117 on: December 09, 2017, 10:36:06 PM »
No.  /WE needs to be driven by the Z80 /WR signal (probably buffered due to fanout limitations).   Put the switch in series with the signal with the pullup resistor on the FLASH side of it.   If you want an indicator LED, use a DPST switch and use the other pole for the LED. 

As an alternative, if you need to mount the switch off-board, or must use a SPST switch, insert an OR gate in line with the /WR signal, and supply a logic level from a switch to the other input.    The extra propagation delay is preferable to running a fast logic control signal to a front panel switch and back.  You cant wire the switch as you have drawn as the LED will prevent the level going low enough for a valid logic 0.  Move the logic takeoff point to the LED cathode and  a 4K7 resistor across the LED to fix it.
« Last Edit: December 09, 2017, 10:45:51 PM by Ian.M »
 
The following users thanked this post: nockieboy

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #118 on: December 10, 2017, 02:21:02 AM »
Right, so based on Ian.M's feedback I've come up with the below:



... but I have no idea where or how to wire up a warning LED with this arrangement?

The switch type I'm using isn't because of any particular reason, its just that I have a few of these knocking about in a drawer.
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #119 on: December 10, 2017, 04:24:24 AM »
To get better at this you need to understand small parts and then put them together into something that works.

Gain some knowledge.
First look at drawing before this with Led.

What is the voltage at top of led ( D1 pin 2 ) with switch opened and closed?

What is logic Low voltage range for /WR pin of ram?
What is logic High voltage range for /WR pin of ram?

Now re-read the last part of Ian.M's post again.

Now dig into  lan.M's post an you have some answers to last drawing.

Hint, logic is logic, output of switch is a logic output.

Now last drawing.
Question is "do you trust your switch and what happens if it has a poor connection?"

 Look at what you want to happen at U4 pin B

If that connection from S1 pin C1 comes loose, what is at U4 pin B?

You have all the answers you need to answer your question from Ian.M's post.

Now go a step further and change how switch is connected.
 Wire the switch with C1 connected to ground.

If you understand Ian.M's post, this is a small change.

Now what happens when connection to U4 pin B gets disconnected or switch fails?

Do not make it hard, take simple steps from first drawing to improversion of last drawing.

 Start here in post

You cant wire the switch as you have drawn as the LED will prevent the level going low enough for a valid logic 0.  Move the logic takeoff point to the LED cathode and  a 4K7 resistor across the LED to fix it.
You should know answers to my above questions if you go step by step changing circuit as lan.M suggests.
Understanding now will save you time later.

Now continue reading lan.M's post.
« Last Edit: December 10, 2017, 04:26:15 AM by C »
 

Offline Kilo Tango

  • Regular Contributor
  • *
  • Posts: 79
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #120 on: December 10, 2017, 05:11:02 AM »
How about using the HD64180 ?. it already has an MMU giving access to 512K of memory plus other facilities. It was marketed as a "Super Z80" and sold by Zilog as the Z180. You can still find them : https://www.ebay.com/itm/Hitachi-64180-Kits-HD64180-MPU-TC551001-128K-SRAM-W27C020-EEPROM-DIP32-/161337103516


An example of its use is at https://www-users.cs.york.ac.uk/~pcc/Circuits/64180/doc.html


Ken
« Last Edit: December 10, 2017, 05:13:49 AM by Kilo Tango »
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #121 on: December 10, 2017, 10:42:21 PM »
How about using the HD64180 ?. it already has an MMU giving access to 512K of memory plus other facilities. It was marketed as a "Super Z80" and sold by Zilog as the Z180. You can still find them : https://www.ebay.com/itm/Hitachi-64180-Kits-HD64180-MPU-TC551001-128K-SRAM-W27C020-EEPROM-DIP32-/161337103516

An example of its use is at https://www-users.cs.york.ac.uk/~pcc/Circuits/64180/doc.html

Ken

Thanks Ken - but the reason I haven't gone for a more modern processor / microcontroller is because it defeats the purpose of doing all this in the first place - to build something similar in capability to my first ever computer, and maybe learn something about electronics at the same time.

You have all the answers you need to answer your question from Ian.M's post.

Now go a step further and change how switch is connected.
 Wire the switch with C1 connected to ground.

If you understand Ian.M's post, this is a small change.

Now what happens when connection to U4 pin B gets disconnected or switch fails?

Do not make it hard, take simple steps from first drawing to improversion of last drawing.

 Start here in post

You cant wire the switch as you have drawn as the LED will prevent the level going low enough for a valid logic 0.  Move the logic takeoff point to the LED cathode and  a 4K7 resistor across the LED to fix it.
You should know answers to my above questions if you go step by step changing circuit as lan.M suggests.
Understanding now will save you time later.

Now continue reading lan.M's post.

I feel as though I'm groping around for solutions here, C, I'll admit.  I don't know whether it's because I've misread what Ian.M and you have written, or if it's because I just don't grasp how it all works.  :-\

Here's the latest version, based off of what you've explained and a re-reading of Ian.M's post:



It's probably entirely wrong but, if it's not, how does the LED not light up when the switch is open?  Surely it's earthed via U4:B?  And what is the purpose of the 4K7 resistor in parallel with the LED?
 

Offline David Hess

  • Super Contributor
  • ***
  • Posts: 5471
  • Country: us
  • DavidH
Re: Z80 memory banking for 128K - MMU design
« Reply #122 on: December 10, 2017, 11:54:36 PM »
It's probably entirely wrong but, if it's not, how does the LED not light up when the switch is open?  Surely it's earthed via U4:B?  And what is the purpose of the 4K7 resistor in parallel with the LED?

The 4.7k resistor pulls input U4:B up fully preventing the LED from lighting up.  Open TTL inputs do not really require pull-ups but they are a good idea.
 
The following users thanked this post: nockieboy

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #123 on: December 11, 2017, 12:13:26 AM »

Your last will work!

The proper connection for the 4K7 is S1 C2 to +5V

Quote
Surely it's earthed via U4:B?  And what is the purpose of the 4K7 resistor in parallel with the LED?

First U4 B is an input, as such very little current can flow out, it is high resistance.

A poor way to think about it, when you put your volt meter across the switch does the led light?
Meter is high resistance.


LED's are very poor diodes.
You get to thinking that diodes are great, current flows in one direction and nothing in the other, NOT THE CASE.
As the voltage across diode increases a small current flows until at some point the current starts increasing fast with little change in voltage.


LED's have a very high Vo that changes by type and color of led.

So looking at your last,

You remove the switch and your are write protected.

If you put the 4K7 resistor close to U4 B then you could even have LED get disconnected and still be in write protected mode.

 
The following users thanked this post: nockieboy

Online glarsson

  • Regular Contributor
  • *
  • Posts: 151
  • Country: se
Re: Z80 memory banking for 128K - MMU design
« Reply #124 on: December 11, 2017, 01:30:23 AM »
Thanks Ken - but the reason I haven't gone for a more modern processor / microcontroller is because it defeats the purpose of doing all this in the first place - to build something similar in capability to my first ever computer, and maybe learn something about electronics at the same time.
Then why all this talking about flash memory and extreme amounts of memory? Imagine that the memory cost is about 5 UKP per kilobyte static RAM and build with what you "can afford".
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #125 on: December 11, 2017, 05:34:30 AM »
Thanks Ken - but the reason I haven't gone for a more modern processor / microcontroller is because it defeats the purpose of doing all this in the first place - to build something similar in capability to my first ever computer, and maybe learn something about electronics at the same time.
Then why all this talking about flash memory and extreme amounts of memory? Imagine that the memory cost is about 5 UKP per kilobyte static RAM and build with what you "can afford".

Similar in capability. If I was going for that level of fidelity, I'd be trying to duplicate my old computer chip-for-chip.  Using something like a Z180 (or whatever) with a built-in MMU, timer and I/O would mean I would be just plugging a couple of chips together to get a working system.  This way I'm learning all kinds of stuff while I'm going and learning how to exceed the spec of my original Amstrad CPC464 in places (like memory size and clock speed currently.) I'm doing the things I wanted to but could never afford to do as a kid (and with information resources like the internet with easy datasheet access, tutorials and forums like this one, that never existed back then.)

 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #126 on: December 12, 2017, 08:59:32 AM »
Your last will work!

It certainly does, C!  ;D  I can now program the ROM without having to remove it from the breadboard - I've impressed myself with how smoothly it went!  8)  I thought I had the ROM iteration down to a quick turnaround before, but now I can just type a command, paste the new ROM Intel Hex into the terminal window and watch as it buffers the data, erases the appropriate sector on the ROM and then writes the new data!  It even does it more quickly that my EEPROM programmer does!

I'm using an SST39SF010A, which has software protection against accidental writes, so there's a sequence of up to three address/value writes I have to do which, considering I'm writing to a RAM Area mapped to an arbitrary ROM Bank, involves some card-shuffling with the MMU to get the write sequence to the correct addresses on the ROM - but it works!  ;D
 

Offline nockieboy

  • Regular Contributor
  • *
  • Posts: 244
  • Country: gb
Re: Z80 memory banking for 128K - MMU design
« Reply #127 on: December 12, 2017, 09:16:55 AM »
Your flash rom has a software protect feature to prevent accidental writes.

You should be able to just connect your existing /WR that goes to RAM to your Rom chip with no problems.

Yes, that's exactly what I've done.  Couldn't be fussed messing around with switches and LEDs in the end when the ROM has software protection against accidental writes and (for the most part) is hidden behind the MMU and not always mapped into view for the Z80 anyway.

With some good code even CP/M2 can use a RAM or ROM drive.

With CP/M3 capability to run a program on CP/M2 and change to CP/M3 you have a great test environment.

Build a NON-Banked version of CP/M3
Use this to build two more CP/M3 versions
CP/M3 with ROM and/or RAM disk drives.
Banked CP/M3
Banked CP/M3 with ROM and/or RAM disk drives.

For future keep in mind that a CP/M disk drive could be a file or array of blocks on PC or something.

Yes, I'm now quite intrigued about the idea of a ROM drive seeing as how quickly writing to (and obviously reading from) the ROM is done.  This little sub-project has been a pleasant diversion from my CP/M 3 BIOS-writing woes, though - I need to get back to that and, in the process, no doubt I'll learn a bit about how drives work in CP/M and be better armed to deal with creating a FLASH ROM-drive later...  :-+
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1049
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #128 on: December 12, 2017, 10:11:56 AM »

With you being able to write to rom you have a good foundation you can build on.

If you have a good copy of Flash Rom, you could
Program the ROM using any programmer and if hardware was working, off you go with a working Z80

Now if a part of that Flash Rom looks like a CP.M disk then
You could boot to CP/M2 or CP/M3

If that CP/M disk has
CF Tools you could create a new CFCard disk drive
  Format new card & put on CP/M boot

If that CP/M disk has
  some comm programs, you could just run a program to send/receive via one of the many file transfer protocols.
  A BBS program would let you really go to town making it easy to move files from Z80 <-> PC

CP/M

You should have a copy of all Digital Research CP/M3 files on your Z80.
By using the relocatable macro assembler that comes with CP/M3 you can have files that work with rest of CP/M3

Run your current assembly files through the rmasm to see what you need to change if you are going to use PC to edit the files.
For small edit changes it could be faster to just startup WordStar3.3 on Z80.

Make Grant's code your own.
Grant has many different source files that only have a small change. This is hard to maintain. That rmasm assembler program for CP/M3 will let you remove this problem. Some will still work with PC assembler.

Think of this
  My Z80 could have many types of disk drives attached, many formats for floppies. Seldom did I need to change CP/M to work with these.
For my system's standard format floppies it would look at what was in the drive and make the needed changes in bios & CP/M.
You can make this easer by having a data table on each drive at a fixed spot.
If is not hard to have first Z80 instructions on a boot track to jump over a data table that has information of disk format.
For PC's this is the Master boot record at the start of drive.


So do not make getting CP/M3 hard.

what CP/M3 wants is a table that has entry points for each character I/O device.  It really wants a driver for a SIO and wants the driver to work with many SIO's.

The same is true of storage. You just need a few chunks of code that will use CP/M3's data tables to find out what to read or write.

One chunk of code to work with RAM/ROM disks.
One chunk of code to work with CFcard drives.

Where CP/M2 left a lot of work on BIOS programmer, CP/M3 does a lot more.
CP/M3 can do the blocking of 128 byte sectors into what the storage needs.
You driver gets simple,
  move this data <-> storage sector.
The What is in the tables but to make it easer to change from CP/M2 will still call set DMA, set drive, set track, ....

So just make a quick hack to Grant's to get it working. Then start making changes that will let you tap into CP/M3's full capabilities.

With CP/M'3 program that can build the CP/M3 drive tables, it could be easer to just skip the CP/M2 interface to bios and just jump to CP/M3's bios interface.
CP/M lets you have 16 drives. You could keep 8 working with Grant's drivers and 8 working with your drivers so that you can test your driver's functions.

A Drive is just chunks of storage that you have to work at a chunk of bytes level. Called a sector of which you put a bunch of sectors on a track and a bunch of tracks makes a drive.

 
 



 
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf