Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Z80 memory refresh register

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

like image 366
PhilPotter1987 Avatar asked Dec 16 '11 21:12

PhilPotter1987


2 Answers

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?

like image 162
user1219475 Avatar answered Sep 26 '22 16:09

user1219475


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).

like image 32
harold Avatar answered Sep 27 '22 16:09

harold