Frage

Me again with another innocuous Z80 question :-) The way my emulator core is currently structured, I am incrementing the lower 7 bits of the memory refresh register every time an opcode byte is fetched from memory - this means for multi-byte instructions, such as those that begin DD or FD, I am incrementing the register twice - or in the instance of an instruction such as RLC (IX+d) three times (as it is laid out opcode1-opcode2-d-opcode3).

Is this correct? I am unsure - the Z80 manual is a little unclear on this, as it says that CPDR (a two byte instruction) increments it twice, however the 'Memory Refresh Register' section merely says it increments after each instruction fetch. I have noticed that J80 (an emulator I checked as I'm not sure about this) only increments after the first opcode byte of an instruction.

Which is correct? I guess it is not hugely important in any case, but it would be nice to know :-) Many thanks.

Regards, Phil Potter

War es hilfreich?

Lösung

All references I can find online say that R is incremented once per instruction irrespective of its length.

Andere Tipps

The Zilog timing diagrams hold the answer to your question.

A refresh occurs during T3 and T4 of all M1 (opcode fetch) cycles.

In the case of single-opcode instructions, that's one refresh per instruction. For single-prefix instructions (prefixes are read using M1 cycles) that's two refreshes per instruction.

For those weird DD-CB-disp-opcode and FD-CB-disp-opcode type instructions (weird because the displacement byte comes before the final opcode rather than after it), the number of refreshes is at least 3 (for the two prefixes and final opcode), but I'm not sure if the displacement byte is read as part of an M1 cycle (which would trigger another refresh) or a normal memory read cycle (no refresh). I'm inclined to believe the displacement byte is read in an M1 cycle for these instructions, but I'm not sure. I asked Sean Young about this; he wasn't sure either. Does anyone know for certain?

UPDATE:

I answered my own question re those weird DD-CB-disp-opcode and FD-CB-disp-opcode instructions. If you check Zilog's documentation for these type instruction, such as RLC (IX+d), you'll note that the instruction requires 6 M-cycles and 23 T-cycles broken down as: (4,4,3,5,4,3).

We know the first two M-cycles are M1 cycles to fetch the DD and CB prefixes (4 T-cycles each). The next M-cycle reads the displacement byte d. But that M-cycle uses only 3 T-cycles, not 4, so it can't be an M1 cycle; instead it's a normal Memory Read cycle.

Here's the breakdown of the RLC (IX+d) instruction's six M-cycles:

  1. M1 cycle to read the 0xDD prefix (4 T-cycles)
  2. M1 cycle to read the 0xCB prefix (4 T-cycles)
  3. Memory Read cycle to read the displacement byte (3 T-cycles)
  4. M1 cycle to fetch the 0x06 opcode and load IX into the ALU (5 T-cycles)
  5. Memory Read cycle to calculate and read from address IX+d (4 T-cycles)
  6. Memory Write cycle to calculate RLC and write the result to address IX+d (3 T-cycles)

(The RLC calculation overlaps M-cycles 5 and 6.)

These type instructions are unique in that they're the only Z80 instructions that have non-contiguous M1 cycles (M-cycles 1, 2 and 4 above). They're also the slowest!

Paul

Sean Young's Z80 Undocumented Features has a different story. Once for unprefixed, twice for a single prefix, also twice for a double prefix (DDCB only), and once for no-op prefix.

Block instructions of course affect R every time they run (and they run BC times).

I've seen a couple of comments now that these weird DDCB and FDCB instructions only increment the R register twice.

It's always been my assumption (and the way I implemented my Z80 emulator) that the R register is implemented at the end of every M1 cycle.

To recap, these weird DDCB and FDCB instructions are four bytes long:

DD CB disp opcode

FD CB disp opcode

It's clear that the two prefix opcodes are read using M1 cycles, causing the R register to be incremented at the end of each of those cycles.

It's also clear that the displacement byte that follows the CB prefix is read by a normal Read cycle, so the R register is not incremented at the end of that cycle.

That leaves the final opcode. If it's read by an M1 cycle, then either the R register is incremented at the end of the cycle, resulting in a total of 3 increments, or the Z80 special cases this M1 cycle and doesn't increment the R register.

There's another possibility. What if the final opcode is read by a normal Read cycle, like the displacement byte that preceded it, and not by an M1 cycle? That of course would also cause the R register to be incremented only twice for these instructions, and wouldn't require the Z80 to make an exception of not incrementing the R register at the end of every M1 cycle.

This might also make better sense in terms of the Z80's internal state. Once it switches to normal Read cycles to read an instruction's additional bytes (in this case the displacement byte following the CB prefix), it never switches back to M1 cycles until it starts the next instruction.

Can anyone test this on real Z80 hardware, to confirm the value of R register following one of these DDCB or FDCB instructions?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top