Driving a Z80 chip with a 'slow' clock

3,251 views
Skip to first unread message

PRL-89

unread,
Jan 27, 2015, 12:26:27 AM1/27/15
to se...@googlegroups.com
Sorry for this lengthy post, but I need some help and advice from the Z80 hardware hackers out there to help explain a mystery. 

A couple of years ago I bought two Z80A CPU chips (Z0840004, the 4 MHz NMOS version); they've been sitting in my parts bin ever since.  I recently decided to check them out.

I used my (Elenco) digital trainer/breadboard to assemble a minimum Z80 test system.  I connected the Z80's 16 address lines and 8 control status lines to individual LEDs, so I could monitor each line's state.  I connected the Z80's /RESET line to one of the trainer's debounced slide switches, so I could hold the Z80 in reset on power on, and reset it at any other time while the clock was running.  I connected all other control input lines (/INT, /NMI, /WAIT and /BUSREQ) to +5, deactivating them.

I connected the Z80's 8 data lines to a simple 8-section DIP switch (one side of each SPST switch tied to ground, the other side connected through a 1K ohm resistor to +5V) so I could set each data line high or low.  By setting the switches to a specific instruction opcode (like 0x00 for NOP), I could watch the Z80's address lines and status lines change as it repeatedly executed that instruction. (Using fixed data line values precludes executing any instructions that generates a memory or I/O write cycle; doing so could short out one or more of the data lines.)

I connected the Z80's CLK line to the trainer's CLK output, a +5V square wave clock signal that can be set to any frequency between approx. 1 Hz and 100 KHz.

I first tested a NOP instruction.  With the data line switches set to 0x00 and the /RESET line switch set to low, I powered on the circuit and watched as the 16 address line LEDs changed, after a couple of clock cycles (the Z80 needs 3 clock cycles to fully reset), from all on (0xFFFF) to all off (high impedance: I have no pull-up resistors), and the 8 status line LEDs from random to all on (inactive).  I then set the /RESET line switch to low (deactivating the /RESET line), causing the Z80 to begin executing NOP instructions repeatedly.  During T1 and T2 of the M1 cycles the address line LEDs showed the PC's value increasing from 0x000 through 0xFFFF; during T3 and T4 (refresh cycle) the address line LEDs showed the IR register pair's value as the R register increased from 0x0000 through 0x007F (the I and R registers are 0x00 following a reset).

Since it was difficult to capture the state of the address and status line LEDs, even with the clock running at its slowest 1 Hz frequency, I decided to instead drive the CLK line with the trainer's other debounced slide switch.  This allowed me to manually generate a clock signal, holding the clock high or low at any time.  Since the Z80, according to legend, 'uses a fully static design', and having seen lots of 'build your own Z80' type circuits that include a manual clock 'step' circuit, I assumed this was an ok thing to do.

With the Z80's CLK line now connected to a debounced slide switch, everything still seemed to behave as expected -- for example, the /M1 status line LED turned off (active/low) at M1-T1 high, while the /MREQ and /RD status line LEDs turned off (active/low) at M1-T1 low, exactly as shown in the Z80 timing diagrams.  But I discovered that if I held the CLK line low for 'too long', the Z80 would sometimes lose its mind: it might, for example, start executing memory read cycles instead of M1 cycles, with the address line LEDs showing some random pattern).  So I learned to 'quickly' toggle the clock's slide switch from high-to-low and back to high again, so that the CLK line wasn't being held low for too long.  That seemed to solve the immediate problem.

I then tried testing some other single-opcode instructions.  I tested JP (HL) by setting the data line DIP switches to 0xE9.  Testing this instruction helped me to determine that the HL register pair contains 0xFFFF following a power-on/reset.  I repeated this test a couple of times to ensure that the 0xFFFF value was not simply a random value assigned at power-on

I next tested the RET instruction, by setting the data line switches to 0xC9.  The RET instruction consists of an M1 cycle, to fetch the opcode, followed by two MRead cycles, to pop the low and high PC values off the stack).  Testing confirmed that the RET instruction requires 10 T-states (M1:4, MRead:3, MRead:3), and that the initial value of SP following a power-on/reset is 0xFFFF. It also confirmed that, because the values read by each MRead cycle is the value of the data line switches (0xC9), the PC's value at the M1 cycle following the RET instruction is 0xC9C9.

So far everything was working exactly as expected.  Until I tested the JR e instruction.

The JR e instruction is a 2-byte instruction consisting of the opcode 0x18 followed by the 'e' operand.  The instruction adds the e operand, as a signed byte, to the current PC, using that value as the address of the next instruction.  The JR e instruction requires three machine cycles, a 4 T-state M1 cycle to fetch the opcode, a 3 T-state MRead cycle to read the 'e' operand, and a 5 T-state ALU cycle to calculate the new PC value and load it into the PC.

Because the data line switches are 0x18 during the MRead cycle, the 'e' operand value is read as 0x18.  The PC's value, incremented twice by the M1 and MRead cycles, is 2, so the expected PC value at the end of the JR e instruction should be 0x0002 + 0x0018 = 0x001A.

But when I tested this instruction, I ended up with a different PC value.  The address line LEDs at the start of the M1 cycle following the ALU cycle was 0x00F6, not 0x001A.  I can't figure out how the PC ended up with the value 0x00F6.

I repeated the test multiple times, all with the same PC = 0x00F6 result.  I tried moving the CLK line from the manual slide switch to my trainer's CLK output, running it at 1 Hz so I could see the see of the value of the address line LEDs during T1-T2 of the second M1 cycle.  Same result.

I checked my trainer's CLK output with a scope, and verified that the square waves looked clean, with virtually no ripple and fast rise and fall times.  I even switched out the Z8 chip for the other one, and still got the same result.

Are my assumptions and calculations correct as to the expected PC value?  What else might explain what's going on?

I then got to thinking that maybe the Z80's clock was the culprit.  Perhaps the clock can't be run slow, or stopped in a high or low state, like others have suggested.  I decided to check the Z80's A.C. characteristics more carefully, to see what they say about the clock's timing limits.  What I found out surprised me.

First, I never realized there was so many versions of the Z80 chip!  As I mentioned, mine is called the Z80A.  I was able to find specs for the original Z80 chip, the Z80A variations (4 MHz, 6 MHz and 8 MHz), as well as CMOS versions of the Z80, also with max clock speed variations (up to 10 MHz).  In all cases the A.C. Characteristics table lists the minimum and maximum clock pulse width, in nsecs, for the clock's high and low pulses.

For the original Z80, the Clock Pulse Width (High) and Clock Pulse Width (Low) minimum is 180 nsecs.  That translates to a maximum clock frequency of approx 2.7 MHz (1 / 360 nsecs).  It's the Clock Pulse Width maximum spec that's interesting.  The Clock Pulse Width (High) maximum is infinity, meaning the CLK line can be held in a high state for any length of time.  But the Clock Pulse Width (Low) maximum is 2000 nsecs (2 usecs).  That means, assuming a square-wave clock with a 50% duty cycle, the minimum clock frequency is 250 KHz (any frequency less than that would generate a clock high pulse longer than 2 usecs).

So what happens if I drive the Z80's CLK line with a manual (debounced) switch, or with a clock running slower than 250 KHz (my trainer's clock's maximum frequency is 100 KHz)?

While hunting around for other Z80 specs, I came across some interesting and confusing differences.  For the CMOS Z80s (Z84C0004, Z84C0006, etc.), all specs listed both the the Clock Pulse Width (Low) maximum and Clock Pulse Width (High) maximum as 'DC'.  That suggests all CMOS Z80 clocks can be run at *any* clock frequency from stopped to its rated maximum, and the CLK line can be held in a high or low state for any period of time.  But for NMOS Z80s, some specs listed the Clock Pulse Width (High) maximum as DC, while others listed it as 2000 nsecs.  All specs listed the Clock Pulse Width (Low) maximum as 2000 nsecs.  If in fact both the Clock Pulse Width (Low) maximum and Clock Pulse Width (High) maximum is 2000 nsecs, then the clock can't be run any slower than 250 KHz; if only the Clock Pulse Width (Low) maximum is 2000 nsecs (the Clock Pulse Width (High) maximum is DC), then it would still be possible to control the clock with a switch or run the clock at a 'slow' frequency, provided the clock's low pulse width is less than 2 usecs.

So that's my mystery.  In a nutshell:
  1. Why isn't my test circuit producing the correct PC value following a JR e instruction (where PC = 2 and e = 0x18)?
  2. Could this error be because the clock is not running 'fast' enough to meet the Z80A's published maximum clock low pulse width (2 usecs)?
  3. What are the correct minimum and maximum Clock Pulse Width (Low) and Clock Pulse Width (High) values for NMOS and CMOS Z80 chips?
  4. Have others successfully used a switch to control the Z80's CLK line, or used a 'slow' clock?
Comments most welcome!

Paul

Jbensadon

unread,
Jan 27, 2015, 9:28:11 AM1/27/15
to se...@googlegroups.com
Hi Paul,

Sounds like everything was going fine until the relative jump.  Thank you for the summary of Z80's, there are definitely a lot of variations of this chip and that's not including the newer chips with SIO's, PIO's and CTC's built in.

On a tangent, it was interesting to learn the 65C02 is not software compatible with the 6502.  But back to the Z80.

So you have a Z80A, which should be static...  I would just the same at this point try a fixed pulse width circuit like a 74LS121 one-shot timer. 

Cheers,
Josh



Date: Mon, 26 Jan 2015 21:26:27 -0800
From: paul....@gmail.com
To: se...@googlegroups.com
Subject: [sebhc] Driving a Z80 chip with a 'slow' clock
--
You received this message because you are subscribed to the Google Groups "SEBHC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sebhc+un...@googlegroups.com.
To post to this group, send email to se...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sebhc/4afbeefe-f570-4071-b55d-0c43215c2185%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Terry Gulczynski

unread,
Jan 27, 2015, 10:11:56 AM1/27/15
to se...@googlegroups.com
Paul,

To start with, I have no idea if what I'm posting will help.  Having said that...

The old Heathkit H89A User Manual contains the Z80 data sheet reprinted from Zilog (way back in the old days.)  The pin descriptions says the following about the clock signal:

"Single phase TTL level clock which requires only a 330 ohm pull-up resistor to +5 volts to meet all clock requirements."

Are you using the pull-up resistor?  Your description doesn't say.  Will the lack of a pull-up cause what you're seeing regarding the clock and 'static' operation?  I dunno, but I suspect it will have some effect.

The more recent Z80 User Manual that has been around for several years does not refer to a pull-up requirement on the clock signal, nor do the follow-on designs for the Z180-series chips.  I suspect this was because of the change over from NMOS to CMOS designs, but I'm just guessing.

You might try again with the pull-up (if you're not using it) and see if there's a difference, particularly with the older chips (NMOS).  Although I can't 'see' the circuit you're using for the clock, I can easily envision that you're applying a ground when the clock is 'off', rather than an otherwise floating but pulled-high signal.  Or perhaps not.  You might want to verify that when you turn the clock 'off', it actually open-circuits the clock, rather than applying a ground.  By leaving the 'off' clock open-circuited (floating) AND having the pull-up resistor in place, you might find some very different results.

One last note - all of my designs, even with the latest Z8S180, include the pull-up resistor.  Having the pull-up, even when not called for by the data sheet, has never caused any negative effects.


Just a guess...  Have fun with it!

Terry


On 1/27/2015 12:26 AM, PRL-89 wrote:

Snipped a bit...


With the Z80's CLK line now connected to a debounced slide switch, everything still seemed to behave as expected -- for example, the /M1 status line LED turned off (active/low) at M1-T1 high, while the /MREQ and /RD status line LEDs turned off (active/low) at M1-T1 low, exactly as shown in the Z80 timing diagrams.  But I discovered that if I held the CLK line low for 'too long', the Z80 would sometimes lose its mind: it might, for example, start executing memory read cycles instead of M1 cycles, with the address line LEDs showing some random pattern).  So I learned to 'quickly' toggle the clock's slide switch from high-to-low and back to high again, so that the CLK line wasn't being held low for too long.  That seemed to solve the immediate problem.
Snipped a bit more...

dwight

unread,
Jan 27, 2015, 10:40:04 AM1/27/15
to se...@googlegroups.com
The earlier NMOS chips used a capacitive boost circuit on the
bus lines to get greater swings. This boost would have decayed
over time.
They may have used some dynamic nets as well. Dynamic
nets would require the clock to cycle to the hold state before
the net decayed. This is most likely what the spec is for.
One could make a simple pulse circuit to single clock.
Dwight

 

Date: Tue, 27 Jan 2015 10:11:59 -0500
From: terr...@cfl.rr.com
To: se...@googlegroups.com
Subject: Re: [sebhc] Driving a Z80 chip with a 'slow' clock
--
You received this message because you are subscribed to the Google Groups "SEBHC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sebhc+un...@googlegroups.com.
To post to this group, send email to se...@googlegroups.com.

PRL-89

unread,
Jan 27, 2015, 9:56:53 PM1/27/15
to se...@googlegroups.com
Thanks everyone for your comments!

Terry, I'll try adding the 330 ohm pull-up resistor to the CLK line and see if anything changes.

Dwight, I 'll come up with a push-button one-shot pulse circuit that drives the CLK line low for max 2 usecs, then returns high.  That would meet the spec, assuming the max clock high pulse width is really infinity.

Paul 

PRL-89

unread,
Jan 31, 2015, 8:02:39 AM1/31/15
to se...@googlegroups.com
Adding a 330 ohm pull up on the CLK line made no difference.
 
In checking around I found someone had made a comment to the effect that if you want to stop the Z80's clock you need to use the CMOS (implying you couldn't do that with the NMOS version). That seems to jibe with the Z80 spec, which lists the CMOS chip's Clock Pulse High max and Clock Pulse Low max as DC.
 
Also, based on the CMOS chip's D.C. characteristics, it looks like (based on my limited understanding of CMOS) its input and output lines are fully TTL compatible. So I should be able to just drop it into my existing proto system.
 
Anyone have experience with the CMOS Z80 chip? Any problems using it with TTL chips?
 
Thanks,
 
Paul

Lee Hart

unread,
Jan 31, 2015, 1:00:35 PM1/31/15
to se...@googlegroups.com
PRL-89 wrote:
> Adding a 330 ohm pull up on the CLK line made no difference.

The 330 ohm resistor was specified in early data sheets because the Z80
clock line needs to go to a solid "high" -- not the ~3v that a typical
TTL gate can do. It's not needed if you have a clock driver that
produces a good solid high and low logic levels. Nowdays, a 74HC gate is
a good choice.

> In checking around I found someone had made a comment to the effect that
> if you want to stop the Z80's clock you need to use the CMOS (implying
> you couldn't do that with the NMOS version).

That's correct. While the NMOS Z80 is nominally static, in fact it was
not tested or designed for it. The CMOS Z80 is truly static.

> Also, based on the CMOS chip's D.C. characteristics, it looks like
> (based on my limited understanding of CMOS) its input and output lines
> are fully TTL compatible. So I should be able to just drop it into my
> existing proto system.

Yes, that is correct. I've never had any problems using a CMOS Z80 in
place of an NMOS Z80, unless there were special-case speed issues. The
CMOS parts are generally faster -- if some "mad designer" depended on
the slower NMOS Z80, the CMOS part might output a timing signal that was
"early" compared to what was expected.

> Anyone have experience with the CMOS Z80 chip? Any problems using it
> with TTL chips?

No, not really. There can be an issue if you have a TTL output driving
both the CMOS Z80 inputs *and* regular TTL chips. The TTL output's
high-state voltage only goes to about 3v when it is driving other TTL
chips. This may not be high enough to make a CMOS input happy. When you
have to do this, include a pull-up resistor (just as was done for the
NMOS Z80's clock line, to get a good high-state voltage).

BTW... If you want to stop the NMOS Z80, it's better to do it with the
/WAIT line than with the clock.
--
Excellence does not require perfection. -- Henry James
--
Lee Hart, 814 8th Ave N, Sartell MN 56377, leea...@earthlink.net

Norberto Collado

unread,
Jan 31, 2015, 2:09:05 PM1/31/15
to se...@googlegroups.com
If you want to debug the Z80 as it executes code, just add a single step circuit. There are so many circuits in the internet such as:

https://z80project.wordpress.com/2014/02/16/single-step-instruction-circuit/

If you want to run the Z80 slowly to see the code being executed on LEDS here is a YouTube video...
https://www.youtube.com/watch?v=sp8oWnOoL4s

Thanks,

Norberto

PRL-89

unread,
Jan 31, 2015, 4:11:15 PM1/31/15
to se...@googlegroups.com
Thanks Norberto,

Yes, I'm familiar with that type of single-step circuit.  It's one of many Z80 single-step circuits that uses the Z80's /WAIT line to start and stop the Z80.  That particular circuit activates the /WAIT line only during an M1 cycle, when the Z80 is about to fetch the next opcode (during T2, CLK high-to-low transition), so you're able to see the external state of the Z80 just after the end of each instruction.  Unfortunately, that type of circuit doesn't give me the clock start/stop control I need.

I've built a Z80 software emulator that accurately executes all of the Z80's internal timings (as part of a larger H89 emulator under construction).  I need to answer a bunch of Z80 timing questions that are not covered by Zilog's spec.  For example, the Z80's M1 timing diagram shows the /RFSH line being activated at the start of T3 and deactivated at the start of T1 of the next machine cycle.  But what if an M1 cycle is longer than 4 T-states (some M1 cycles use 5 or 6 T-states)?  Is the Refresh cycle 'stretched' in those cases?  (Answer: No.  For M1 cycles that use more than 4 T-states, the /RFSH line gets deactivated at the start of T5).  Another more interesting (to me) question: For 'double prefix' instructions like DD CB (always 'IX+d' type instructions), the byte sequence is: 0xDD, 0xCB, d, opcode (yes, the d displacement byte comes before the main opcode). Like all other prefixed instructions, the Z80 uses M1 cycles to read each of the DD and CB prefixes.  It's also fairly obvious that the Z80 would use a Memory Read cycle to read the d displacement operand.  But what type of machine cycle is performed to read the main opcode?  Is it another M1 cycle? (Answer: No, it's a Memory Read cycle.  This is the only case where the Z80 does not activate it's M1 line to fetch an instruction opcode,  That means the R (Refresh) register is only incremented twice when executing these double-prefix instructions, even though these instructions contains three opcodes (two prefixes and the main opcode).  Unless you're writing an emulator, you probably don't care about any of this! :-)

To answer these sorts of questions, I need to be able to stop the Z80 at each half clock cycle (CLK high and CLK low), so I can monitor the Z80's address, data and status lines as its CLK line transitions from low-to-high and high-to-low.  For example, I was able to answer my question about the double-prefix instructions by checking the state of the /M1 status line at the start of T2 of the machine cycle following the Memory Read cycle that read the d displacement byte.  If this were an M1 cycle the /M1 line would be activated.  It wasn't.  Instead only the /MREQ and /RD lines were activated, indicating a Memory read cycle.  I could further confirm this by stepping the clock one more T-state (T3) and seeing that the /RFSH line was not activated.

Ultimately I want to end up with a Z80 test circuit that allows me to switch between three clock modes: single-step, 'slow' clock speed (say, 1 Hz) and 'normal' clock speed.

It looks like the CMOS version of the Z80 will let me hold the Z80's CLK line high or low for an indefinite period of time, at least according to the spec.  I'll see if that's true when I get my CMOS chip and swap it in for the NMOS chip I'm currently using.


Paul

On Tuesday, January 27, 2015 at 12:26:27 AM UTC-5, PRL-89 wrote:

PRL-89

unread,
Jan 31, 2015, 4:15:48 PM1/31/15
to se...@googlegroups.com
Hi Lee,

Thanks for clearing up some questions about the CMOS Z80.  That helps a lot.

See my long-winded response to Norberto to understand why I want start-stop control of the Z80's clock (vs using the /WAIT line).

Paul

Lee Hart

unread,
Jan 31, 2015, 6:29:25 PM1/31/15
to se...@googlegroups.com
OK; got it!

But since you are delving deep into the Z80's timing cycles: Be aware
that there were licensed Z80 clones and *unlicensed* Z80 clones. Also,
nothing says that the CMOS and NMOS Z80's have identical timing!

One example is the Ferranti NMOS Z80. It was an unlicensed clone, and
was 99% (but not 100%) Z80 compatible. As I recall, there were some
small differences in how it handles the flags, so certain software
programs could tell the difference.

I also read an article on Zilog's CMOS Z80 that said that they
"improved" some of the instruction timing over the NMOS part. I think I
ran into this problem when I tried to use a CMOS Z80 in the old Sinclair
ZX80 computer. It didn't work. Something in Clive Sinclair's "mad
genius" circuit could tell the difference, and didn't work right.

Norberto Collado

unread,
Jan 31, 2015, 6:58:16 PM1/31/15
to se...@googlegroups.com
Hello Paul,

OK, I now understand why you need to control the Z80 Clock. Have you consider in buying a cheap USB analyzer that could help you out while running the Z80 clock at least at 1Hz? I was able to develop my Z67-IDE controller thanks to a vintage SCSI  logic analyzer that I was able to rescue.

Norberto

Jbensadon

unread,
Feb 1, 2015, 11:17:55 AM2/1/15
to se...@googlegroups.com
Hi Paul,

Those are some fascinating details about the Z80.  Nice work on your part for chasing down the "truth".  Gives truth tables a whole new meaning :)  That's amazing how the 'd' is sent before the rest of the opcode.

Like Norberto said, I believe a nice logic analyzer will go a long way to help you.  They are your "microscope" to look into the world of microseconds (and nanoseconds).

Here's a funny story... but I wasn't laughing until I found the problem.  On a recent board, I was testing my firmware with a 27C256, then I switched to a 29C256 for faster reprogramming of the chip, but the firmware stopped working.  It was the 8080 board on the IMSAI, so I would examine memory through the front panel and verify the opcodes were correct, and they were.  A full RUN mode caused the address lines to go beyond the small short test loop.  I simplified my program to just a JMP 0000, and it still wouldn't work at full RUN speed!!!  Go back to the 27C256 EPROM and it works!!! 
I then used my logic analyzer on it... the access speed of the FLASH memory dropped to something in the millisecond range (nothing I would notice by using the Examine function).  The reason for this drop in speed is because I left pin 1 of the EPROM/FLASH chip floating.  This is an unused pin for the EPROM, but obviously the FLASH ROM requires it be pulled high.

Moral of the story... leave no pin unturned!  oh, and a Logic analyzer is your best friend.

Cheers,
Josh Bensadon



Date: Sat, 31 Jan 2015 15:58:14 -0800
Subject: Re: [sebhc] Re: Driving a Z80 chip with a 'slow' clock
From: norberto...@koyado.com
To: se...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "SEBHC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sebhc+un...@googlegroups.com.
To post to this group, send email to se...@googlegroups.com.

PRL-89

unread,
Feb 1, 2015, 2:59:11 PM2/1/15
to se...@googlegroups.com
Hi Josh,

I enjoyed your story about the floating Flash pin!  I agree, I'm trying to verify the Z80's behavior using 'poor man's tools' (a debounced clock switch and a bunch of LEDs). :-)  Yes, a logic analyzer would certainly make all of this much easier!

Re the d displacement byte appearing before the main opcode in DD CB and FD CB prefixed instructions:  That fact is documented in Zilog's Z80 CPU User's Manual.  What's not documented is, for these and many other Z80 instructions, exactly what type of machine cycles are executed to complete the instruction.  For example, Zilog indicates that the RLC (IX+d) instruction has these timings:

M Cycles           T States
     6             23 (4,4,3,5,4,3)

(The numbers in parentheses are the number of T-states required by each of the 6 machine cycles.)

The RLC (IX+d) instruction consists of these four bytes:

0xDD
0xCB
d displacement
0x06

The first two machine cycles are 4 T-state M1 cycles used to read the DD and CB prefixes.  The next machine cycle is a 3 T-state MRead cycle to read the d displacement byte.  The next machine cycle is a 4 T-state cycle to read the main opcode (0x06), but Zilog never says what kind of machine cycle it is.  I initially assumed it was another M1 cycle, since the Z80 uses M1 cycles to read instruction prefixes and opcodes.  But I had found some discussions on the Internet noting that the R register is incremented only twice for these types of 'double prefix' instructions.  That suggested to me that the Z80 must be executing only two M1 cycles, not three, for these types of instructions.  My testing confirmed that the fourth machine cycle, the one reading the main opcode, is a 5 T-state MRead cycle, because the M1 status line is never activated during that cycle.  I suspect the Z80 needs the extra two T-states at the end of this MRead cycle to calculate the address IX+d, and store that address in its internal WZ register pair, although I have no way to confirm this through the address, data and status lines.

To finish the RLC (IX+d) instruction's analysis: The fifth machine cycle is a 4 T-state MRead cycle to read the contents of memory address IX+d, load it into the accumulator and rotate it (I'm assuming the rotate operation occurs at the end of this cycle because this cycle is one T-state longer than a normal MRead cycle).  The last machine cycle is a 3 T-state MWrite cycle to write the result back to memory address IX+d.

Paul

dwight

unread,
Feb 1, 2015, 3:35:59 PM2/1/15
to se...@googlegroups.com
You can always capture the various bits of data at the end of the
clock low and then return the clock to the safer high state.
Just because the CMOS version is CMOS is no assurance that
you can leave the clock low for an arbitrary amount of time.
Dynamic circuit exist in CMOS designs.
Dwight

 

From: jben...@hotmail.com
To: se...@googlegroups.com
Subject: RE: [sebhc] Re: Driving a Z80 chip with a 'slow' clock
Date: Sun, 1 Feb 2015 11:17:54 -0500

PRL-89

unread,
Feb 1, 2015, 4:18:11 PM2/1/15
to se...@googlegroups.com
Dwight,

I'm not sure I understand your comment re CMOS.  If the CMOS Z80 spec's A.C. Characteristics table lists Clock Pulse Width (High) maximum and Clock Pulse Width (Low) maximum as 'DC', under what conditions would I not be able to hold the Z80's CLK line high or low for an indefinite period?

Paul

Chris Elmquist

unread,
Feb 1, 2015, 8:08:03 PM2/1/15
to se...@googlegroups.com
That's what you need-- an overt statement that you can put the clock
at a DC level and keep it there. They usually made a big deal about
it if it was possible.

I think to Dwight's point-- just because it's made from a CMOS process
does not make it static. You can also have CMOS devices with dynamic
nodes that will decay without being clocked. Just like you can have NMOS
devices that are static and can tolerate the clock stopping-- see eg,
Intel 8080.

As long as you have a spec that says you can stop the clock, you should
be good.

Chris
--
Chris Elmquist

PRL-89

unread,
Feb 1, 2015, 11:56:44 PM2/1/15
to se...@googlegroups.com
Thanks Chris.  Yes, I agree.  To Dwight's point, there's certainly nothing inherent in CMOS that would somehow cause the Z80's internal registers and flags to be static.

It's fairly well documented that the Z80 was designed so its internal registers and flags are static, allowing you to slow down or stop the clock.  That's why you find so many 'build your own Z80 computer' articles on the Internet that includes some sort of single-step or 'slow' clock circuit.

So I was surprised to learn from reading the Z80 specs more carefully that the NMOS version imposes a maximum clock low pulse width of 2 usecs.  There's some confusion as to the NMOS Z80's maximum clock high pulse width; some specs state the maximum clock high pulse width is DC, while others that state the maximum clock high pulse width is 2 usecs (same as the maximum clock low pulse width).  If in fact the maximum clock high pulse width is DC, then you could create a single-step circuit that held the clock high by default, then triggered a less-than-2-usec one-shot low pulse when you pressed the 'step' button.  But if the maximum clock high pulse width is 2 usecs, then there's no way to single-step the clock; the best you could do would be to slow the clock down to no less than 250 KHz (2 usec high pulse + 2 usec low pulse).

Paul

Jbensadon

unread,
Feb 2, 2015, 11:35:13 AM2/2/15
to se...@googlegroups.com
Hi Paul,

re Floating flash pin, of course, when I ran into the problem, I was testing the next progressive step of my firmware, although it was very early in the development, I thought I had made an error in my coding.  So I spent some good time trying to troubleshoot something that wasn't broken.  I don't recall, but I believe even the single step worked, since I was stepping the processor 1 cycle at a time on the IMSAI.  So, I have this program that works in slow motion, but not at full speed!  To compound the problem, I've successfully used this same FLASH ROM in several other projects, I even have a ZIF socket on a dip header, so I can swap chips very fast (helps keep my mind focused on the code).  Bottom line, it was a very annoying problem that had me looking in all the wrong places.

re Z80.  Yeah, I know the timing you are looking for.  It's written for the 8080, exactly what happens on each T state.  It must be written somewhere for the Z80, but not likely published.

I would agree with your assumptions regarding the 4,4,3,5,4,3 T states.  And it's a great find on your part regarding the state of the M1 line through these instructions.  It's not going to be possible to know what happens on every T state, but your guesses sound very reasonable.  I am wondering if it's possible to RESET the CPU in the middle of a cycle then examine the registers?  I am going to guess, or perhaps I read it in the data sheet? that the RESET is only sampled on specific cycles/t-states?  and/or there might be some logic that requires RESET to be low for a few cycles?
What about monitoring the current?  If you shift 00 with carry=0, and record the current draw in each t state, then repeat the experiment with carry=1 (ie, now  you have something that will toggle off after the shift), then any current draw difference(s) from the baseline experiment should be when the shift actually took place?

Just food for thought.  It will probably take too much time to try, and your assumptions seem accurate enough for a realistic emulator.  Besides, what difference does it make with regards to what is going on inside your emulator, so long as the outside pins are behaving the same way?

PS. You probably already know this... OUT (c) and IN (c) will put B on the high address bus during the I/O.

Cheers,
Josh





Date: Sun, 1 Feb 2015 11:59:11 -0800
From: paul....@gmail.com
To: se...@googlegroups.com
Subject: [sebhc] Re: Driving a Z80 chip with a 'slow' clock
--
You received this message because you are subscribed to the Google Groups "SEBHC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sebhc+un...@googlegroups.com.
To post to this group, send email to se...@googlegroups.com.

PRL-89

unread,
Feb 2, 2015, 2:05:23 PM2/2/15
to se...@googlegroups.com
Hi Josh,

Thanks, I can appreciate the frustration tracking down a software problem when you never quite trust the hardware. :-)

The Z80's timings are very well documented, in both the Zilgo CPU User Manual and Z80 technical Manual.  The timings in the technical manual are a bit more accurate.  My emulator attempts to match those timings, within reason (it doesn't, for example, take into account line delays measured before or after the clock's leading or trailing edges, only that a line changes state during the correct T-state.  Even this can be a little tricky.  For example, during an M1 cycle both the /MREQ and /RD lines are activated during the low phase of T1.  But the spec'd delays are such that /MREQ might go active slightly before or after /RD. (My emulator simply activates /MREQ first, then /RD, during the low phase of T1).  Events (a.k.a. callbacks) are used to notify external components when a status line changes state, so it's up to those components to deal with the order of status line activation.

There's some interesting design decisions in the H89 based on Z80 timing.  One is the inclusion of a simple RC circuit that delays the buffered Z80 /MREQ line by approx. 65 usecs (the DMERQ L and DMREQ H lines).  It was unclear to me why this delay was needed until I better understood how the U517 bank decoder ROM worked.  U517 uses only the buffered /RD line (BRD L) and buffered /RFSH line (BRFSH L) to differentiate between the three Z80 memory requests: Read (/RD active + /RFSH inactive), Write (/RD inactive + /RFSH inactive) and Refresh (/RD inactive + /RFSH active).  It does not use the buffered /WR line, BWR L.  If you look at the timing diagram for a Z80 Memory Write cycle, you'll see that the value to be written to memory is first loaded onto the data lines during the low phase of T1. The /WR line is not activated until almost a full clock cycle later, during the low phase of T2.  That gives the data lines plenty of time to stabilize before a memory device reads the data.  For the H89, adding a 65-usec delay to the /MREQ line provides 'enough' time for the data lines to stabilize before the U517 is selected (which in turn selects the correct memory device to read the data lines), even though the Z80's /WR line is still inactive at this point.  I'm guessing this design worked well enough for the 'slower' Z80's (2 MHz versions) and avoided having to come up with a more complex decoding scheme that used the /WR line (all eight of the U517 ROM's input lines were already accounted for).

Just another one of those 'interesting to me' discoveries.

Yes, it's well-documented that for the various I/O instructions the high order A8-A15 address lines contain either the A or B register (A reg for IN A,(n) and OUT A,(n), B reg for all others).  I recall that some Z80 implementations take advantage of that fact to extend the I/O address port range from 8 to 16 bits.

By the way, did you know the Z80 has a couple of undocumented I/O instructions:

     OUT (C)     0xED + 0x71     Write 0xFF to the I/O port specified in register C.

     IN (C)        0xED + 0x70      Read value from the I/O port specified in register C,
                                              updates flags, then discard the input value.

Lots of these undocumented Z80 goodies can be found at www.worldofspectrum.org.

Paul

PRL-89

unread,
Feb 12, 2015, 9:37:40 AM2/12/15
to se...@googlegroups.com
Here's an update.for those interested in this topic.

I was able to get the JR e instruction to work correctly by simply increasing the clock's frequency.  I had been either single-stepping the clock or running it at 1 Hz, so I could watch as the address, data and status lines changed during each clock cycle of the JR e instruction.

To see if a too-slow clock speed might be the cause of the failure I increased the clock's frequency to approx. 20 Hz.  I then shot a 5-sec video of my test circuit while the Z80 repeatedly executed the JR e instruction.  I then stepped through the video frame by frame to capture the address, data and status lines at each T-state of the first two JR e instructions.  Lo and behold, that instruction now worked correctly (the PC value on the address lines at the start of the 2nd M1 cycle was now the expected 0x001A value).

So it appears this issue was clearly the result of running the clock too slow.  Obviously running the clock at 20 Hz still doesn't come close to meeting the NMOS Z80's min clock pulse width (20 Hz means each clock cycle is 50 msecs; each high and low pulse is 25 msecs); the NMOS spec says the min clock low pulse is 2 usecs).  Still, at least this instruction started working with the clock running at 20 Hz.  Your chip's mileage may vary.

I have other instructions to retest.  The RST p instructiion was also failing (the restart address was incorrect) when single stepping the clock or running it at 1 Hz. 

I'll be getting a CMOS Z80 chip in the next day or two.  I'll then find out if that version of the chip really does allow me to single-step the clock or run it at very low frequencies.

Paul

PRL-89

unread,
Feb 18, 2015, 10:24:35 AM2/18/15
to se...@googlegroups.com
One more update...

With my new CMOS Z80 installed (Toshiba TMPZ84C00AP-4), I was able to stop the clock in a high or low state for any amount of time (even hours) without affecting the Z80's internal state.

All of the Z80 instructions I had previously tested, like JR e, that produced wrong results with the NMOS version of the chip now worked fine.

The moral of my story: if you want to be able to single step the Z80's clock or run it very slowly, be sure to use a CMOS version of the chip.

Paul

Mark Garlanger

unread,
Feb 18, 2015, 8:51:36 PM2/18/15
to se...@googlegroups.com
Hi Paul,

    Are you documenting your findings anywhere besides your emulator?  I have a bunch of questions about some initial states of things.

Mark


--
You received this message because you are subscribed to the Google Groups "SEBHC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sebhc+un...@googlegroups.com.
To post to this group, send email to se...@googlegroups.com.

Paul Laba

unread,
Feb 18, 2015, 9:46:05 PM2/18/15
to se...@googlegroups.com

Hi Mark,

 

Good to hear from you!

 

If there’s some specific questions you have re Z80 initial states, ask away and I’ll be happy to try to answer them.

 

The first question I wanted to answer was: What is the initial state of registers and flags following a power-on/reset?

 

Assuming the Z80 is held in reset for at least three clock cycles following power-on, all registers except PC, I and R are set to 0xFF or 0xFFFF.  The PC, I and R registers are zeroed following any reset; no other registers are affected.  (It’s been claimed that a reset sets SP to 0xFFFF; not so.)

 

The one exception I discovered is that the F register is initially 0x64 (01100100B), not 0xFF as I expected.  Strange.  I determined that value by executing a PUSH AF instruction immediately after power-on/reset and checking the state of the data lines during T2 of the second memory write cycle (A is written first to (SP-1); then F is written to (SP-2)).  The data lines contains 0xFF during T2 of the first memory write cycle (pushing A onto the stack), but 0x64 during T2 of the second  memory write cycle (pushing F onto the stack).  I need to play around with this one some more and see if I can figure why F seems to be an exception to the ‘all-bits-set at power-on/reset’.

 

Paul

--
You received this message because you are subscribed to a topic in the Google Groups "SEBHC" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sebhc/xB5t-s6zX1o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sebhc+un...@googlegroups.com.


To post to this group, send email to se...@googlegroups.com.

PRL-89

unread,
Feb 18, 2015, 10:25:34 PM2/18/15
to se...@googlegroups.com
Mark, re my last reply...

The initial F register's value is 0x6C (01101100B), not 0x64.  That means the Z, P/V and unsupported X and Y flags are set initially; the S, H, N and C flags are clear.

I tested the PUSH AF instruction three times and got the same result every time.  It's possible a different Z80 chip might produce a different result.

Paul

John Toscano

unread,
Feb 18, 2015, 11:12:25 PM2/18/15
to se...@googlegroups.com

Paul: Your statement about the value of the SP register on reset seems to contradict itself. You say that all registers except PC, I, and R are set to 0xFF or 0xFFFF, and those three are set to 0. Then you say that it has been claimed incorrectly that SP is set to 0xFFFF but this is "not true". So, what DOES happen to SP? It better have some determined value (pointing to RAM somewhere) if a PUSH instruction is going to be executed...

Sign me confused (John, W0JT)

PRL-89

unread,
Feb 18, 2015, 11:42:13 PM2/18/15
to se...@googlegroups.com
Hi John,

Sorry for the confusion.  Let me try again.

When you first power on the Z80, assuming you hold /RESET low for a minimum of three clock cycles (if you don't the Z80 may go insane), the SP register will contain the initial value 0xFFFF at the end of the reset.  If you were to then execute the instruction PUSH BC, the B register (0xFF) would be written to address 0xFFFE and the C register (0xFF) to address 0xFFFD.  At the end of the instruction the SP register contains the value 0xFFFD (the top of the stack).  If you were to then reset the Z80 (by holding its /RESET line low for a minimum of three clock cycles), the SP register (and all other registers except PC, I and R) would not be affected.  At the end of the reset, when the Z80 resumes execution, the SP register will still contain the value 0xFFFD.

To prove this, I single-stepped the clock through a complete PUSH BC instruction (10 T-states), verifying that the two memory writes were to addresses 0xFFFE and 0xFFFD.  At the end of the instruction I lowered the /RESET line for three clock cycles, forcing a new reset.  After a couple of clock cycles I then raised the /RESET line, and, two clock cycles later, the Z80 started executing a new PUSH BC instruction (at address 0x0000 since the reset zeroed the PC).  But the next two memory writes were to addresses 0xFFFC and 0xFFFB, confirming that the reset had not changed the SP register's value.

Hope that helps.

Mark Garlanger

unread,
Feb 18, 2015, 11:48:39 PM2/18/15
to se...@googlegroups.com
Cool, lots of good info for my emulator.

The the other details I was looking for, were related to other parts of the H89. Like, what are the setting for the serial port as it powers up, before any programming. What are the values of the GPP(General Purpose Port - 0xf2) at power up? My emulator is working, but it would be good to make sure the initial state, and how it behaves after resets are accurate to a real H89.

Mark


--
You received this message because you are subscribed to the Google Groups "SEBHC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sebhc+un...@googlegroups.com.
To post to this group, send email to se...@googlegroups.com.

PRL-89

unread,
Feb 19, 2015, 7:11:02 AM2/19/15
to se...@googlegroups.com
Hi Mark.

By serial port do you mean the H89's terminal serial port (U561) on the CPU logic board?  If so, that chip's Master Reset pin 35 is connected to the system reset line and is reset when the H89 is first powered on or is reset via SHIFT+RESET.  I never pulled the 8250 off the board to check it's initial state; I relied instead on the 8250's documentation.  See page 14-3 of the H88 Operations Manual for a description of the 8250's state following a master reset.  I think Les's web site has a copy if you don't already have one.

Re the General Purpose Port (GPP) initial state:  The data lines on the GPP's input port (U551, a 74LS244 octal tri-state buffer connected to the SW501 switches) are in a high-impedance state except when the U550 I/O port decoder selects it (pin 6 is active/low) and the Z80's /RD line is active/low, so the lines are in a high-impedance state at power-on/reset.  The GPP's output port (U552, an 74LS273 octal D flip-flop) has its MR pin 1 tied to the system reset line, so all eight of its output lines Q0-Q7 are low (0) whenever the H89 is initially powered on or is reset via SHIFT+RESET.

An interesting emulation question is whether it's useful or necessary to emulate a chip or circuit's initial power-on state if a reset signal is not applied.  Obviously that's up to the designer.  My Z80 emulator does emulate the Z80 'losing its mind' if a clock signal is applied to the chip following power-on and its /RESET line is not held low for at least three clock cycles.  But my H89 emulator (still in progress) assumes that the system reset signal is active/low for several msecs following initial power-on, since that's how the circuit is designed and implemented.  So when a new instance of my Z80 class is created within my H89's CPULogicBoard class, the Z80 class's RESETLine property (representing the state of the /RESET line) is initially set to active/low.  The PowerOnReset class (representing the CPU logic board's power-on/reset circuit) within the CPULogicBoard class handles deactivating the Z80's /RESET line once the initial power-on reset timer has elapsed.

Paul

John Toscano

unread,
Feb 19, 2015, 10:38:18 AM2/19/15
to se...@googlegroups.com

Ok, sorry I failed to pick up on the distinction between first reset after power-on (set SP to 0xFFFF) and subsequent resets (leave SP alone). But I am curious about another aspect of the SP behavior. As you describe it, with the SP set to 0xFFFF, the pushed values go into memory locations 0xFFFE and 0xFFFD, not into 0xFFFF (where SP is pointing) and 0xFFFE. If this is true, SP doesn't point to TOS (where next byte goes) but rather to BOS (where the last byte went). Is this correct, i.e. in the scenario you describe, the very last byte of memory @0xFFFF is not written to?

--

John Toscano

unread,
Feb 19, 2015, 11:51:45 AM2/19/15
to se...@googlegroups.com
I'm curious, but have no working Z80 system to try this on. Assume the following program:

MVI A, 0x0A          ; set A register to 0x0A
MVI B, 0x0B          ; set B register to 0x0B
MCI C, 0x0C         ; set C register to 0x0C
LXI H, 0xFFFF      ; set HL register to last memory address, 0xFFFF
SPHL                    ; set SP equal to HL, i.e. both now pointing to 0xFFFF
MOV M,A              ; put contents of A (0x0A) into memory where HL points (0xFFFF)
PUSH B                ; push BC (0x0B0C) onto stack
HALT

I would expect that 0xFFFF gets set to 0x0A, but then the PUSH instruction writes 0x0B0C into 0xFFFE and 0xFFFF,
i.e. since the Z-80 is "little-endian", 0xFFFE gets 0x0C and 0xFFFF gets 0x0B, overwriting the value that was first
put into 0xFFFF.

But Paul's description would say that 0xFFFD gets 0x0C, 0xFFFE gets 0x0B, and 0xFFFF retains 0x0A.

So, which is right? All the years that I programmed Z-80's I assumed that the stack pointer was pointing at the top
of the stack, i.e. where the next byte gets pushed.

John

John Toscano

unread,
Feb 19, 2015, 11:54:07 AM2/19/15
to se...@googlegroups.com
Ouch, the third instruction should have been MVI C, 0x0C, not MCI C, 0x0C.
:jpt:
362.gif

PRL-89

unread,
Feb 19, 2015, 5:06:08 PM2/19/15
to se...@googlegroups.com
Hi John,

Yes, that's correct.  The Z80 pre-decrements SP when pushing a register onto the stack, and post-decrements SP when popping a register off the stack.  As such, if SP contains the address n, the next push onto the stack will write to addresses n-1 and n-2.  At that point SP does point to the top of the stack: the lsb of the last word pushed onto the stack.

If nothing has yet been pushed onto the stack, then SP points 'just past' the top of the stack.  That's why, with SP = 0xFFFF initially, executing a 'PUSH qq' instruction writes qq msb to address 0xFFFE and qq lsb to address 0xFFFD, with SP pointing at qq lsb (at 0xFFFD) at the end of the instruction.

Obviously it's critical that SP be initialized correctly before interrupts are enabled or anything is pushed onto the stack; otherwise bad things will happen.

Most of the Z80 software I've seen initially assigns to SP the highest RAM address.  What it should do is assign it the highest RAM address + 1.  For example, if you want the stack to begin at 0xFFFF (the highest 64K address), SP should be assigned the value 0x0000, not 0xFFFF.  By assigning SP the value 0x0000, the first push onto the stack will write to addresses 0xFFFF and 0xFFFE.  Assigning 0xFFFF to SP in this case effectively 'wastes a byte', since no push will write to address 0xFFFF.

Paul

Paul Laba

unread,
Mar 13, 2015, 1:55:11 PM3/13/15
to se...@googlegroups.com

Hi Mark,

 

First, Happy Birthday! (I got a notice from Outlook.com).  Hope you’re not turning into an old guy like me. J

 

Second, I wanted to follow up on your message re Z80 initialization.

 

Because I wrote my Z80 emulator to run independently of my H89 emulator, I couldn’t simply force the Z80’s /RESET line to be active/low at the time the Z80’s clock was started.  (I suppose I could have done that, but since the Z80 doesn’t have any sort of self-reset-at-power-on feature, I would have been cheating.)  My H89 emulator holds the Z80’s /RESET line active/low for a fixed number of clock cycles when the clock is started at power on, since the H89’s CPU logic board provides a circuit to do just that.

 

I found some differences in behavior between my NMOS Z80 chip and CMOS Z80 chip.  In general the CMOS chip is better behaved.

 

With both chips I found all registers to be in their ‘all bits set’ state with the exception of the F (flags) register.  Oddly, I saw a couple of different F register values when I powered on the chip.  (To determine the value of the F register, I executed a PUSH AF instruction following reset, which loads the F register onto the data lines during the first memory write cycle; the values on the data lines sometimes varied but were never 0xFF.  Pushing any other register pair always produced 0xFF on the data lines during the memory write cycles.)

 

Also, I discovered that, if I started the clock without holding the /RESET line active/low, the CMOS Z80 chip ‘wasted’ a couple of cycles but then started executing an M1 cycle with PC=0x0000, just as would normally happen when the Z80 comes out of reset.  The NMOS Z80 chip on the other hand went a bit crazy, activating various status lines in odd combinations.  Sometimes it would eventually start a normal M1 cycle, in other cases it would just cycle through a sequence of odd states.

 

One interesting observation with the CMOS chip: With the /RESET line held low at power on, if I then start the clock, it takes one or two clock cycles before the address and data lines are floating and the status  lines are all inactive/high.  This is to be expected because the Zilog documentation says it takes three clock cycles before the reset is “accepted”.  In fact , the Z80 only samples the /RESET line during low-to-high transitions, so depending on when the /RESET line is activated, it takes two samples to put the Z80 into reset (on the 3rd sample).  What’s curious is what the Z80 is actually doing for those first two clock cycles.  The behavior seems different if the /RESET line is active/low when the clock starts following power-on, versus the /RESET line becoming active after the Z80 has started normal processing.  In the first case, those two clock cycles seems to do nothing; in the latter case those two cycles are normal processing cycles.  For example, once the Z80 has started normal processing, if the /RESET line becomes active/low at the start of T2 of a normal M1 cycle, the Z80 will execute the T2 and T3 cycles as normal, then go into reset at the start of T4 (address and data lines floating; all status lines inactive/high).  But when the clock is started with the /RESET line active/low following power on, the next two clock cycles appear to do nothing.

 

Of course, the only clues I have in all this is the Z80’s address, data and status lines, so I can’t know what’s going on internally.  I know there are smart people out there that have reverse engineered the Z80’s gates and can better speak to its internal workings than me.

 

By the way, how did your ‘raw’ disk format project finally turn out?  I thought that was a great design, and I’m planning to implement it in my H89 emulator (it will support the standard *.h8d disk images as well as your .raw disk images.  With the option to save a disk image file, I can save a disk image in either format, which will allow me to convert any h8d formatted disk image into a raw disk image.  The obvious advantage to your raw format, besides being a more accurate image of a floppy disk, is being able to save the disk’s volume ID, something you can’t do with the h8d images (since they contain no header fields).

 

Take care,

 

Paul

 

From: se...@googlegroups.com [mailto:se...@googlegroups.com] On Behalf Of Mark Garlanger
Sent: Wednesday, February 18, 2015 11:49 PM
To: se...@googlegroups.com
Subject: Re: [sebhc] Re: Driving a Z80 chip with a 'slow' clock

 

Cool, lots of good info for my emulator.

Mark

--
You received this message because you are subscribed to a topic in the Google Groups "SEBHC" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sebhc/xB5t-s6zX1o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sebhc+un...@googlegroups.com.


To post to this group, send email to se...@googlegroups.com.

dwight

unread,
Mar 13, 2015, 11:47:15 PM3/13/15
to se...@googlegroups.com
The reset line is considered an asynchronous input. In order
to avoid metastable conditions, the designers used a 2 stage
pipeline on the reset input ( we currently use a  3 stage where
I work ).
Nothing magical about the two clock cycles, going on.
If it didn't try to eliminate a metastable condition on the
flops that were intended to be reset, some might see the
reset while others did not ( even digital chips are really analog
in how they operate ).
CMOS often has a powerup preference state, depending
on the design of the flops used. You were lucky the state engine
was always in a happy state.
Dwight

 

From: prl...@comcast.net
To: se...@googlegroups.com
Subject: RE: [sebhc] Re: Driving a Z80 chip with a 'slow' clock
Date: Fri, 13 Mar 2015 13:55:12 -0400

Gregg Chandler

unread,
Mar 14, 2015, 12:30:07 PM3/14/15
to SEBHC
The volume id of HDOS diskettes is stored in the label sector.

Mark Garlanger

unread,
Mar 14, 2015, 1:30:06 PM3/14/15
to se...@googlegroups.com
Hi Paul,

    Thanks, I'd like to think I'm not old, mid-40s, so not TOO bad.

    As for the disk image format. I think the format is basically finalized, I was trying to get some more time to get the FC5025 imaging generating these images and verify that no other sections would be helpful for the image. I've attached the current draft spec for it. Let me know if you see any problems, or have any other ideas for it. I don't expect many changes at this point, but maybe some additional sections.

Mark

H17Disk.pdf

Paul Laba

unread,
Mar 14, 2015, 2:10:34 PM3/14/15
to se...@googlegroups.com

Hi Gregg,

 

Yes, thanks.  While it’s true that HDOS stores the user-specified volume ID in the Label sector of a floppy at the time the disk is initialized, it also stores the volume ID in the Volume field in the header of each sector.

 

My H89 emulator, which includes a floppy disk controller emulator, needs to correctly read and write all of the bits stored on a floppy, including both user and header data.  The standard .h8d disk images provide only user data (256 bytes per sector), not the header data.  So my emulator creates each sector’s header data ‘on the fly’ when a new h8d disk image is loaded.  That’s easily to do, except for the Volume field in the header.  In the case of h8d images my emulator could get that value from the Label sector, but that would be cheating — the emulated floppy controller should know nothing about the format or content of the 256-byte user data in each sector, or how a particular OS might organize the data on the disk.  Instead, my emulator currently zeros the Volume field in the header of each sector, even though that might not be the correct value.

 

Mark’s raw disk format is ideal for my (still-in-progress) floppy disk controller emulator because it provides an image of all the bits stored on a floppy disk, regardless of which OS (HDOS, CP/M, etc.) might have written those bits.  Furthermore, the captured bits in a raw image file can start anywhere on the disk — the image file need not organize its data starting with track 0, sector 0 — since the raw disk image includes the necessary status bits (TRK0 and HOLE) to map each captured bit to a specific track, sector and offset with the sector.  (The only requirement is that the number of bits captured in each track be the same.)

 

Paul

Paul Laba

unread,
Mar 14, 2015, 2:15:56 PM3/14/15
to se...@googlegroups.com

Thanks Mark, I’ll give this a good read and offer any comments, suggestions.

 

Paul

 

P.S.  I have a few (too many) years on you.  But I’ve decided to stop aging at this point, so I’ll let you know when you’ve caught up.

Gregg Chandler

unread,
Mar 14, 2015, 5:11:07 PM3/14/15
to SEBHC
Paul:

I am well aware of, and intimately familiar with, the H-17 diskette format.  I suspect that I even understand “why” Gordon did put the id in the header.  However, any (H8 or H89) software that used the H-17 firmware to read/write H-17 diskettes, or attempts to be compatible at the hardware level, either 1) must store the id on the disk somewhere, or 2) use a fixed id to avoid storing it and changing it for tracks beyond track-0.

All emulators make some assumptions.  Mine, by ignoring the header data, can accommodate images from all media types:  H17, H37, H47, and H67.  Additionally, I can support media sizes and types never originally supported by the Heath hardware, or even possible on that hardware.  While I might “cheat” by your standards, it accomplished my goals of being able to archive and support old data and programs—including rebuilding of the system itself.

It is my belief that all engineering is the “art” of compromise.  A Ferrari would be a poor choice for a family vacation.  Likewise, a Mini-Van would be a poor choice for a car race.  Neither design “cheats” in any way.  They make different compromises to accomplish different goals.  If your goal is to emulate every transistor of an H-89, that is fine.  Mine was not.

I chose to emulate the disk sub-system at the block interface level.  That simplification allowed me to focus on virtualization of the file system, and permitted me to integrate the HDOS file system with the underlying host file system—in my case Windows, but just as easily Unix, or something else.  The ability to virtually mount Windows folders as HDOS devices proved quite valuable in accomplishing my goals of archiving and supporting of programs and data, and even networking to data possibly stored on a different host.  I can edit on HDOS, or I can edit on Windows.  I can assemble within the HDOS assembler on a Windows computer.  I don’t need to either modify source, or create a compatible cross assembler—although both are probably easily done.

I made other design decisions, such as emulating the console UART as an ‘rlogin’ connection, which allowed me to remotely access my emulated H-8.  I did not emulate the Z-80 instruction set—as it wasn’t necessary for HDOS 2.0.  I did emulate the H-8 front panel with seven segment displays, sound, etc.

Gregg

Paul Laba

unread,
Mar 14, 2015, 5:20:48 PM3/14/15
to se...@googlegroups.com

Thanks Dwight,

 

I’m not a hardware guy, so ‘metastable condition’ is a new term to me.  I think I get the concept, and it helps me understand why the Z80 needs two full clock cycles before it ‘accepts’ the reset (Zilog says three, but my testing showed that two consecutive low-to-high clock transitions with the /RESET line active/low is enough to force the reset), and what might be going on during those two clock cycles).

 

In the case of my CMOS Z80 chip, I can’t say that the chip always starts life in a ‘happy state’, but it never seems to lose its mind the way the NMOS chip does if I start the clock with the /RESET line inactive/high.  Sometimes when I power on the CMOS chip with the /RESET line active/low, the address and data lines are already floating, other times it takes one or two cycles before they float. In the case where I activate the /RESET line after the clock has started, it always takes both of those two ‘acceptance’ clock cycles before the address and data lines start floating (unless those two clock cycles would have normally had them floating).

 

Paul

Paul Laba

unread,
Mar 14, 2015, 6:11:45 PM3/14/15
to se...@googlegroups.com

Hi Gregg,

 

I appreciate all your comments, and have certainly found myself at times ‘mired’ in compromise when designing and building my Z80 and H89 emulators.  (I can’t tell you how many times I went through major redesigns with my Z80 emulator, trading off hardware accuracy to achieve better performance.)  I set out from the start to build emulators that mimicked the hardware as closely as possible without ending up with Spice. J  And my ‘cheating’ reference was from the perspective of my own design requirements; I certainly understand that other emulators might have a different design center, so their definition of ‘cheating’ could vary significantly from mine.

 

My H17 floppy disk emulator needs to load and save single floppy disks in the form of disk images stored on the host OS (in my case, Windows).  The h8d disk image format is one way to represent an H17 floppy disk’s data, limited to 256 user bytes per sector.  In my case I wanted image files that contained all of the data found on an disk, not only the user data.  Mark’s raw data design provides that. My emulator will work fine with either type of image file, although I will need to generate the missing header data, since my floppy drive controller emulator emulates the S2350 USRT chip and needs to handle all the bits passing under a drive’s read/write head.

 

My goal is to implement both disk image formats, so that I can load and save disk images in either format, and providing a ‘for free’ conversion from one format to the other.  The intent isn’t to inject a competing format with the h8d images, only to end up with disk images that more closely align with my emulator’s design goals.

 

Paul

 

 

 

From: se...@googlegroups.com [mailto:se...@googlegroups.com] On Behalf Of Gregg Chandler
Sent: Saturday, March 14, 2015 5:10 PM
To: SEBHC
Subject: Re: [sebhc] Re: Driving a Z80 chip with a 'slow' clock

 

Paul:

--

You received this message because you are subscribed to a topic in the Google Groups "SEBHC" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sebhc/xB5t-s6zX1o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sebhc+un...@googlegroups.com.
To post to this group, send email to se...@googlegroups.com.

dwight

unread,
Mar 15, 2015, 10:58:30 PM3/15/15
to se...@googlegroups.com
Hi Paul
 When I first wrote the code to deal with disk images
for the H89, it was for the purpose of extracting the data
parts to restore disk that were damaged from swapping without
save ( unmounting ). These were from my brother-inlaw.
I added the code to bootstrap a machine without a disk
with a boot image. I just thought it might be useful for others.
I knew how to do it so I did.
Mark's was intended to make images of the disk including headers.
Because of my original purpose, the headers would have just been
in the way. What I was interested in doing was finding continuous
fragments of text that my brother-inlaw had entered. These were used
to paste together as much of the original text as possible.
Use one or the other as you feel appropriate. Both have their own
reason to exist.
Dwight
 
 

 
Subject: RE: [sebhc] Re: Driving a Z80 chip with a 'slow' clock
Date: Sat, 14 Mar 2015 18:11:44 -0400
You received this message because you are subscribed to the Google Groups "SEBHC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sebhc+un...@googlegroups.com.

To post to this group, send email to se...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages