Question

Considering this sample code:

ZilogZ80A cpu = new ZilogZ80A();
cpu.GeneralRegisters.H.FromUInt(229);
cpu.GeneralRegisters.L.FromUInt(90);
Console.WriteLine("H : " + cpu.GeneralRegisters.H.ToString());
Console.WriteLine("L : " + cpu.GeneralRegisters.L.ToString());
Console.WriteLine("HL: " + cpu.GeneralRegisters.HL.ToString());

Console.WriteLine("Load 23268 (0x5AE4) into register HL...");
cpu.GeneralRegisters.HL.FromUInt(23268);

Console.WriteLine("H : " + cpu.GeneralRegisters.H.ToString());
Console.WriteLine("L : " + cpu.GeneralRegisters.L.ToString());
Console.WriteLine("HL: " + cpu.GeneralRegisters.HL.ToString());

Which is doing the following:

  • Load 229 (decimal) into register H
  • Load 90 (decimal) into register L
  • Print out the values (hex, binary MSB, decimal) of the H, L and HL registers
  • Load 23268 (decimal) into register HL
  • Print out the values of the H, L and HL registers again.

Sample output:

H : 08-bit length register (@45653674): 0x00E5 | MSB 0b11100101 | 229
L : 08-bit length register (@41149443): 0x005A | MSB 0b01011010 | 90
HL: 16-bit length register (@39785641): 0x5AE5 | MSB 0b01011010 11100101 | 23269
Load 23268 (0x5AE4 into register HL...
H : 08-bit length register (@45653674): 0x00E4 | MSB 0b11100100 | 228
L : 08-bit length register (@41149443): 0x005A | MSB 0b01011010 | 90
HL: 16-bit length register (@39785641): 0x5AE4 | MSB 0b01011010 11100100 | 23268

Now for the questions:

  1. Are the above assumptions (and sample output) on how the registers function correct?
  2. Do the other register pairs (AF, BC, DE) function the exact same way?
  3. If the answer to 1. and 2. is yes, why is the Z80 then considered little endian? When the HL register contents gets written to memory the L byte goes first, but (when reading them sequentially afterwards the bytes surely are in big endian order)?
Was it helpful?

Solution

Yes — HL is composed of H as the most significant byte, L as the least. If you perform a 16-bit operation like ADD HL,BC then carry from the top bit of L+C will flow into the computation of H+B. All the register pairs are alike in this regard.

That's because the logical order things are written in isn't related to endianess. E.g. in C you don't have to write 0x0001 on some platforms to equal 0x0100 on others. When writing, you write the most significant first.

The z80 is little endian because if you were to store HL to memory, L would be written a byte before H. If you were to read, L would be read from the address before H.

OTHER TIPS

ld hl, $1234
ld ($fc00), hl

At this point, H = $12, L = $34, as your code suggests. The byte at $fc00 = $34, and the byte at $fc01 = $12. So if you subsequently do:

ld hl, $5678
ld ($fc02), hl

($fc00) = $34, ($fc01) = $12, ($fc02) = $78, and ($fc03) = $56. So reading byte by byte from $fc00, memory would be $34127856, instead of $12345678, because Z80 is little endian.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top