I am currently developing a GameBoy emulator. While coding I started to question how adding to a register affects it.
There are eight 8 bit registers and four 16 bit registers on the cpu. The 8 bit registers can be combined to form 16 bit registers. Here is how I have represented them in code.
struct Registers{
//8 bit registers
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
uint8_t e;
uint8_t f;
uint8_t h;
uint8_t l;
//16 bit registers
uint16_t af;
uint16_t bc;
uint16_t de;
uint16_t hl;
};
QUESTIONS:
If a lower register has the value of 0b11111111 and I add 1 to it. Does that bit carry on to the higher register, or does it wrap around to the beginning of the lower 8 bit register.
If a low register has the value of 0b00000000 and I sub 1 from it, Does it remain zero, or does that bit wrap to the top of the register.
If a high register has the value of 0b00000000 and I sub 1 from it, does it affect the lower register.
To start, I don't think your way of organizing the registers is a good one, since you have duplicated information (storing both a, f and af). One option would be to use unions; unions ensure that two variables share the same memory location. So, you could do:
struct Registers{
union{
struct{
uint_8t f;
uint_8t a;
};
uint_16t af;
};
// And so on for the rest...
};
This way you can manipulate each of the 8bit registers individually (registers.a) or both at the same time (registers.af). Note that if you are developing in a big endian machine, f and a should be swapped to ensure the correct endianness.
If your compiler doesn't support anonymous structs and unions, i think a better option would be to make a function that manipulates the two 8 bit registers and shifts them to form a 16bit register. This way you don't have to access both a and af every time you modify them.
Now to your actual question. My information is based both from this table (which contains some errors i've been told, so better to look at other sources to confirm them), and this manual.
Question 1: No, it doesn't carry to the higher register, it will overflow.
Question 2: Same thing, it wraps to 0xFF.
Question 3: Assuming you are using 8 bit ALU operations, then no, again it doesn't affect it.
Note that if you are using 16 bit ALU operations, then they would affect the other register. For example:
Assuming SP = 0x00FF;
ADD SP, 0x1 #Now SP does contain 0x0100 because you used 16 bit arithmetic.
However:
Assuming HL = 0x00FF;
ADD L, 1 # L Overflows to 0x00, however HL = 0x0000 because you used 8 bit arithmetic