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:
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:
The register is neither big-endian nor little-endian; it's just a register holding a 32-bit value. The rightmost bit is the least significant bit, and the leftmost bit is the most significant bit. Some people classify a register as a big-endian, because it stores its most significant byte at the lowest memory address.
Broadly speaking, the endianness in use is determined by the CPU. Because there are a number of options, it is unsurprising that different semiconductor vendors have chosen different endianness for their CPUs.
In the case of the Game Boy the order is 0xFF16 - in other words the least significant byte is first in memory. This scheme is known as little-endian and its opposite is known as big-endian.
Bit order usually follows the same endianness as the byte order for a given computer system. That is, in a big endian system the most significant bit is stored at the lowest bit address; in a little endian system, the least significant bit is stored at the lowest bit address.
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With