5

I'm designing a Z80 system from scratch. My approach is to only have one memory device, a big SRAM, that covers the entire 64 KB memory block.

A sub-system on the board will be a microcontroller (MCU). It will be connected to a PC by a UART and have an I2C EEPROM on it as well. The idea is that this MCU subsystem will be a bootloader of sorts. From the PC you can upload code and also store it in NVM. The MCU would be connected up to all of the bus signals, but only as inputs while in a passive state to let the Z80 run.

According to the Z80 handbook, an MCU can gain control of the bus with the /BUSRQ signal. During that time, according to how I read the datasheets, the MCU can drive the address bus, data bus and bus control signals /MREQ, /IORQ, /RD and /WR.

So an MCU could pull an image out of the I2C EEPROM and load it into the SRAM. However, this might be awkward for the Z80 when the MCU releases /BUSRQ to let it have the bus: it will have to come out of a reset condition instead, to boot from the software image properly.

So Plan B would be to hold the Z80 in reset and do the software load. Is it known that all of the Z80 bus control pins are tri-stated during a reset condition?

Are there known issues with working the bus while a Z80 is held in reset, versus by /BUSRQ?

A stretch goal is that the MCU could also be a debugger, if it is fast enough (and the Z80 slow enough) for the MCU to passively recognize a specific bus address and then assert /BUSRQ. According to the rules of /BUSRQ, an MCU should then be able to browse the SRAM or I/O devices and, when done, the Z80 would pick back up as if nothing happened. Is that a safe assumption?

TonyM
  • 3,704
  • 1
  • 19
  • 31
Smith
  • 153
  • 4
  • 1
    Don't forget pullups to Z80 strobes so that while nobody drives the bus, it is not accessing and destroying SRAM by induced noise or leakage on undriven strobes. – lvd Dec 26 '22 at 19:28
  • @lvd, by 'destroying SRAM', do you mean 'corrupting SRAM data' rather than destroying the IC? – TonyM Dec 26 '22 at 19:48
  • I believe that Ivd means corrupting, physical damage is unlikely. – Frog Dec 26 '22 at 21:13
  • Using a micro as a debugger would be possible but tricky as there’s no immediate way to read the Z80 registers. If you were really keen (and I’m guessing you are otherwise you wouldn’t be doing this at all) you could get the micro to copy a few bytes of RAM, insert some op codes to dump the registers and then jump back to the breakpoint, get the micro to put the RAM contents back as they were and then let the Z80 continue. That’s all possible but perhaps more complicated than debugging the code by getting the micro to emulate a Z80. – Frog Dec 26 '22 at 21:20
  • @Frog It may not work, or just work partly (like not getting any internal registers). But if one has set up an external device to load the RAM on a kind-of-ROM-less system, then you aren't far from being able to watch the address bus and to hold the MPU on a break-pointed address. Worth a shot... – Smith Dec 27 '22 at 21:54
  • @Smith most certainly, and if you design code so that values aren’t stored for long in registers then it’s a minor inconvenience. You could possibly implement a front-panel mode like the RML380Z if you felt the urge. – Frog Dec 28 '22 at 00:45
  • Interesting question! Co-incidentally, I just simulated a simple CPU (in VHDL) that borrowed a lot from the Z80, and included BUSREQ so that I could load a program from a "ROM" into RAM. And, I was wondering about how to best solve the exact same thing, getting the CPU to reset its program counter, and if that should be its own separate "reset" pin (since all BUSREQ uses might not want to reset the program counter. ) I was leaning towards using both BUSREQ and RESET. – BipedalJoe Jan 05 '23 at 15:41

1 Answers1

5

From the Z80 CPU User Manual:

During reset time, the address and data bus enter a high-impedance state, and all control output signals enter an inactive state.

Note the subtlety here:

  • Address and data bus are not driven (“tri state” / “high impedance”)
  • Control output signals are actively driven to the inactive state (!MREQ is high, for example)

This is done to prevent noise from randomly driving the bus during reset. Attempting to also drive it from your microcontroller will result in what is effectively a short circuit between the Z80 and the AVR!

So, you either need some additional logic to let your microcontroller also drive the control signals, or, as @the busybee mentions in a comment, use BUSRQ to tri-state the entire bus, and then use RESET to start the Z80 at a known PC.

Some good news, since you are using static RAM, you won’t need to worry about missing refresh cycles. Make sure you hold !RESET low for at least 3 Z80 clock cycles.

(I won’t answer the second half of your question because it’s about a microchip from the current century, which is off topic here.)

Jacob Krall
  • 2,299
  • 2
  • 17
  • 31
  • 1
    Using both could save that AND gates, first using /BUSRQ to access the RAM, and then /RESET to start the Z80. – the busybee Dec 25 '22 at 17:51
  • 2
    "All control output will enter inactive state" means that in reset, all of /MREQ, /RD and /WR are driven high. If you just connect /MREQ, /RD and /WR to /CE, /OE and /WE on the SRAM, you need to adapt that. You might want to use a sufficiently fast AND gate to mix the MCU and the CPU control signal. – Michael Karcher Dec 26 '22 at 17:10
  • 1
    I incorporated both of your comments; thanks very much for helping clarify this answer – Jacob Krall Dec 26 '22 at 19:27
  • @MichaelKarcher is right, however no extra gates is needed. MCU exits reset with all pins in Z-state. Then it asserts /RESET, then /BUSRQ, waits for /BUSAK and only after that it activates pins connected to the bus addr/data/strobes. Same goes the other way: It removes drive from bus, removes /BUSRQ, applies /RESET. – lvd Dec 26 '22 at 19:30
  • The 'good news' bit is strange and possibly confusing for some readers. OP specified SRAM in their question and never mentioned DRAM, so why is there extraneous text about irrelevant refresh cycles in the answer? – TonyM Dec 26 '22 at 19:53
  • 1
    @lvd I didn't find specification whether the Z80 responds to /BUSRQ while /RESET is asserted (low). I thus suggest to release /RESET after asserting /BUSRQ before waiting for /BUSAK. – Michael Karcher Dec 27 '22 at 10:14
  • With the appropriate time delay in each step, the procedures are as follows. To take Z80 bus, MCU will: assert /BUSRQ, wait for /BUSAK low OR for n CLKs, use SRAM. To release Z80 bus, MCU will: stop using SRAM, assert /RESET, negate /BUSRQ, negate /RESET. – TonyM Dec 27 '22 at 11:39
  • Thank you all for pointing out that subtlety with the control signals. I've been bit by such subtleties in datasheets before. I'm glad for all the experience here to help underline it. I'll rely on interacting with the bus only in /BUSRQ state, not in reset. – Smith Dec 27 '22 at 21:52
  • @TonyM I think it's good to mention that such a scheme is conditional on using SRAM, while DRAM would be problematic. Someone else reading this answer later on might otherwise overlook the difference. – Smith Dec 27 '22 at 22:05
  • @Smith, that's not what's written, it's a very poor explanation of that. – TonyM Dec 27 '22 at 23:19