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

0 Members and 1 Guest are viewing this topic.

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #50 on: November 14, 2017, 03:45:16 pm »
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: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #51 on: November 14, 2017, 04:10:05 pm »

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: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #52 on: November 14, 2017, 04:28:32 pm »

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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #53 on: November 14, 2017, 11:27:44 pm »
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: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #54 on: November 15, 2017, 12: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

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26751
  • Country: nl
    • NCT Developments
Re: Z80 memory banking for 128K - MMU design
« Reply #55 on: November 15, 2017, 12: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: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #56 on: November 15, 2017, 12: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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #57 on: November 15, 2017, 03:01:37 pm »
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: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #58 on: November 15, 2017, 05:56:44 pm »
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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #59 on: November 15, 2017, 09:59:10 pm »
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 15, 2017, 10:13:31 pm by nockieboy »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #60 on: November 15, 2017, 11:41:23 pm »

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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #61 on: November 19, 2017, 10:19:01 pm »
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: 16544
  • Country: us
  • DavidH
Re: Z80 memory banking for 128K - MMU design
« Reply #62 on: November 20, 2017, 12: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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #63 on: November 20, 2017, 09:26:47 am »
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: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #64 on: November 20, 2017, 07:12:24 pm »
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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #65 on: November 21, 2017, 10:09:30 am »
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: 16544
  • Country: us
  • DavidH
Re: Z80 memory banking for 128K - MMU design
« Reply #66 on: November 21, 2017, 03:56:57 pm »
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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #67 on: November 22, 2017, 09:47:20 pm »
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: 12805
Re: Z80 memory banking for 128K - MMU design
« Reply #68 on: November 22, 2017, 10:06:33 pm »
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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #69 on: November 23, 2017, 02:09:38 pm »
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: 12805
Re: Z80 memory banking for 128K - MMU design
« Reply #70 on: November 23, 2017, 02:40:59 pm »
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: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #71 on: November 23, 2017, 03:13:13 pm »
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 23, 2017, 03:58:22 pm by C »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #72 on: November 23, 2017, 04:17:14 pm »
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 23, 2017, 04:24:03 pm by nockieboy »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: Z80 memory banking for 128K - MMU design
« Reply #73 on: November 23, 2017, 06:43:30 pm »
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 nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: Z80 memory banking for 128K - MMU design
« Reply #74 on: November 23, 2017, 10:23:52 pm »
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:
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf