Z80 memory update register

I again with another harmless question Z80 :-) Since the core of the emulator kernel is currently structured, I increment the lower 7 bits of the memory update register every time the byte of the operation code is extracted from memory - this means that for multi-byte instructions, such like those that start DD or FD, I increment the register twice - or in the case of an instruction such as RLC (IX + d) three times (since it is laid out opcode1-opcode2-d-opcode3).

It is right? I'm not sure - the Z80 manual is a bit unclear, as this suggests that the CPDR (double-byte command) increases it twice, however, the section “Memory Update Register” simply says that it increases after each sample of commands. I noticed that the J80 (the emulator I checked as I am not sure about that) only increases after the first byte of the instruction operation code.

What is right? I think this is not very important in any case, but it would be nice to know :-) Thank you very much.

Regards, Phil Potter

+7
source share
4 answers

All the links that I can find on the Internet say that R increases once per instruction regardless of its length.

-one
source

Zilog timing charts contain the answer to your question.

During T3 and T4, an update occurs in all M1 cycles (operation code sample).

In the case of instructions with a single code, this is an update for each instruction. For instructions with one prefix (prefixes are read using M1 loops), there are two updates for each command.

For these strange instructions such as DD-CB-disp-opcode and FD-CB-disp-opcode (strange because the offset byte comes before the final operation code, not after it), the number of updates is at least 3 (for two prefixes and final opcode), but I'm not sure if the offset byte is read as part of the M1 cycle (which would cause another update) or a regular memory read cycle (without updating). I am inclined to believe that offset bytes are read in the M1 loop for these instructions, but I'm not sure. I asked Sean Young about this; he was not sure either. Does anyone know for sure?

UPDATE:

I answered my question: these are strange DD-CB-disp-opcode and instructions FD-CB-disp-opcode. If you check the Zilog documentation for these type instructions, such as RLC (IX + d), you will notice that the instruction requires 6 M-cycles and 23 T-cycles, broken down by: (4,4,3,5,4,3 )

We know that the first two M-cycles are M1 cycles for extracting the prefixes DD and CB (4 T-cycles each). The next M-loop reads the offset byte d. But this M-cycle uses only 3 T-cycles, not 4, so it cannot be an M1 cycle; instead, it is a normal memory read cycle.

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

  • M1 loop to read the 0xDD prefix (4 T-loops)
  • M1 loop to read the 0xCB prefix (4 T-loops)
  • Memory Read cycle to read the offset byte (3 T-cycles)
  • M1 cycle for obtaining the operation code 0x06 and loading IX into the ALU (5 T-cycles)
  • Read memory cycle for calculating and reading from address IX + d (4 T-cycles)
  • Memory write cycle for calculating RLC and recording the result for address IX + d (3 T-cycles)

(RLC calculation covers M-cycles 5 and 6.)

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

Floor

+11
source

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

Block instructions, of course, affect R every time they start (and they start BC).

+5
source

I saw a couple of comments when these strange DDCB and FDCB commands only increment the R register twice.

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

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

DD CB disp opcode

FD CB disp opcode

It is cleared that both prefix codes are read using M1 loops, causing the R register to grow at the end of each of these loops.

It is also clear that the offset byte following the CB prefix is ​​read by a regular read cycle, so the R register does not increase at the end of this cycle.

The final operation code remains. If it is read in the M1 cycle, then either the R register increases at the end of the cycle, resulting in a total of 3 increments, or special cases Z80, this cycle M1 does not increase the R register.

There is another possibility. What should I do if the final operation code is read by a normal read cycle, for example, the offset byte preceding it, and not by the M1 cycle? This, of course, will also cause the R register to be increased only twice for these instructions and not require the Z80 to make an exception without increasing the R register at the end of each M1 cycle.

It may also make sense in terms of the internal state of the Z80. When it switches to regular read cycles to read the instruction of extra bytes (in this case, the offset byte after the CB prefix), it never switches back to M1 cycles until it starts the next instruction.

Can someone check this on real Z80 hardware to confirm the value of the R register after one of these DDCB or FDCB instructions?

+1
source

All Articles