4

I am trying to build a Z80 computer inspired by Grant Searle's design. I'm starting simple, with just a clock (clocked by an AVR pulsing at at 12.5 Hz for testing), a Z80, and a 8K EEPROM with a simple program loaded:

0001   0000            .ORG $0000
0002   0000 00         START:         NOP
0003   0001 C3 00 00                  JP      START
0004   0004            .END
tasm: Number of errors = 0

I have A0-A10 connected and of course D0-D7, and all the usual control pin connections per the design. The violet "DATA" bus line on the scope picture below is simply D0-D7 shown as hex.

I wanted the simplest program I could write that had at least one non-zero opcode in it so that I could observe the data bus on my scope and see the data.

It works as expected for perhaps two minutes after a clean reset, then it starts acting weird, showing this:

SCOPE OUTPUT

Based on the assembled object code, I cannot understand how it ever leaves the C3-00-00-00-00 loop it should stay in. I cannot explain how I'm seeing a 39 or an FF at any time on the data bus as the program runs. Can someone suggest what I might have wrong to create such weird output?

Also notice the unusual coincidence of the FF and the /RD signal being active. When it fails, the /RD signal quits going low. That makes no sense to me. Any ideas?

UPDATE:

If I speed the clock up 10x to 125 Hz, it starts the weird pattern in just a few seconds, not a few minutes.

7
  • 1
    Memory refresh cycle? Or interrupt happening accidentally?
    – Justme
    Commented Mar 22, 2019 at 0:54
  • 1
    /INT is tied high with a 1K resistor. /RFSH is not connected as it is an output.
    – TomServo
    Commented Mar 22, 2019 at 1:08
  • 1
    How about /NMI and /BUSRQ? They need pullups too. Commented Mar 22, 2019 at 3:02
  • 1
    I don't mean /RFSH being connected incorrectly, but the chip supports performimg DRAM refresh cycles internally with the R register as address counter.
    – Justme
    Commented Mar 22, 2019 at 6:05
  • 1
    To find out what CPU is doing you must have /M1 and /RFSH on the scope.
    – Anonymous
    Commented Mar 22, 2019 at 7:27

3 Answers 3

3

[Not a direct answer, just a few remarks and ideas how to proceed]

FF looks much like reading outside any responding memory, doesn't it? Without seeing the address it's hard to see where it's running.

  • So you may want to show some address lines - if short of inputs, start with A2 and up.

  • While at it, add M1 to the display, as this will show if the CPU is running or halted for whatever reason.

M1 in combination with address lines is much more informative of what the CPU does than data lines or read signal. You're debugging a ROM system; here memory content is well known (hopefully) and constant (as well).

Did you clear the ROM before usage or are there any leftovers?

The mentioned /INT and /NMI signals are a great source of confusion, here especially /NMI, as regular interrupts are disabled after Reset. So you may want to have a similar routine at 66h.

Also, /BUSREQ may scramble up any interrupt (on an NMOS at least).

My suggestion:

  • Make sure the ROM is cleared.
  • Add your (Reset) loop at 00h
  • Add another loop at 66h for NMI
  • Monitor M1 and A7..A0 building a hardware trace utility
  • Check where the CPU runs.

I wouldn't change the hardware otherwise, as the intention is to see what's going wrong, isn't it?

With this your scope should give you a nice instruction level trace of

  • 00/01/00/01 when running as expected, or
  • 66/67/66/67 after an NMI (maybe add a button), or
  • anything else when running wild.

Now, when changing the setup, make sure all external requests are nicely tied to +5V. Each and every one with its own resistor to prevent any spike spilling over. This means /WAIT, /INT, /NMI and /BUSREQ.

Also, you should not connect the write input of the EEPROM (just saying :))

2
  • 2
    If there's nothing else on the databus (like RAM, IO) one can wire the bus to 0xC3 (via resistors of say 1-10k), so that CPU will execute endless jumps to 0xC3C3. This is NMI- and INT-proof. Also /BUSRQ and /WAIT would only temporarily stop bus cycles, not crashing the execution sequence.
    – lvd
    Commented Mar 22, 2019 at 12:34
  • @lvd Yes, that works as well and is complete hardware based - nothing but clock required to get it running. Always a good start. I just tried to think along his existing setup, as that's where he comes from. On an original NMOS Z80 /BUSREQ may screw the NMI. so just to get possible bus influence of the table pulling both up is a good idea - simplifies scoping as well.
    – Raffzahn
    Commented Mar 22, 2019 at 14:28
7

If your Z80 is a NMOS one (Z084000* or Z80*), it can't run at frequencies lower than ~250kHz. Specifically, current datasheets for NMOS Z80 state that the maximum time clock signal could be constant (either 0 or 1) is 2 µs.

The reason for that apparent weirdness is that NMOS Z80 heavily relies on NMOS transmission gate latches, which significantly lower the total transistor count, but have a drawback of not tolerating long static periods. Look at this introduction to dynamic logic circuits (page 3 has an exact picture of the transmission gate latch).

3
  • 1
    Or replace your CPU with a CMOS type - these can go much lower.
    – tofro
    Commented Mar 22, 2019 at 9:35
  • Mine is a modern CMOS version rated at 10MHz.
    – TomServo
    Commented Mar 22, 2019 at 9:45
  • 2
    Then, what your breadboard is looking like? If you have too long wires coming from your AVR to Z80, it could easily happen that there is ringing and Z80 accepts glitches as (in)valid extra clocks. Is the AVR powered off 5v? Do all the chips have proper decoupling with nearby ceramic capacitors?
    – lvd
    Commented Mar 22, 2019 at 9:51
2

My problem was floating inputs. Long ago, when I started this project, Grant Searle's schematic did not show a 3k3 pullup on /INT. Now, it does. I inserted 1K pullups on all Z80 input pins, not just on /INT as I mentioned earlier and now it works like a charm.

I also patched the ROM image in the three places where the constants "RTS_LOW" and RTS_HIGH" appear. I changed them from D6 and 96 to D5 and 95. This change of one bit in the 68B50 setup allows me to run at 115,200 bps on a 1.8323 MHz RX/TX clock. The Z80 is using an 8.192 MHz clock. It's working great now.

Thanks for the many useful tips, everyone!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .