Thread: [Tutorial] Hex (Byte) / Binary (Bits)
View Single Post
Old November 21st, 2012 (9:24 AM).
miksy91's Avatar
miksy91 miksy91 is offline
Dark Energy is back in action! ;)
Join Date: Oct 2008
Location: A small country in the North
Gender: Male
Nature: Relaxed
Posts: 1,435
Learning the following is almost mandatory if you ever think about learning programming, and how different number systems work. I've needed this knowledge myself for G/S/C hacking for a long time but if you're going to hack any of 3rd gen pokemon games, it's recommended you learn this kind of stuff too (VBA's Memory Viewer will turn out quite handy if you do, not to mention all the other stuff you can learn later on).

General information

Each byte consists of 8 smaller parts called bits. Byte values can vary anywhere between 00 and FF while bit values can only be 0 or 1.
If you think about it, a byte value in decimal is anywhere between 0 and 255 leaving 256 choices for the value of the byte.
Bytes consists of 8 bits which all can have the values of 0 and 1 (2 choices).

Now the first bit can be 0 or 1, second can be 0 or 1, ..., and eight can be 0 or 1. Naturally, 8 bits can this way form a byte in 2^8 different ways.
And 2^8=256. Makes sense, doesn't it?

Because every byte can be formed exactly in one way from the 8 bits consisting it, every bit has its own "magnitude" in the byte.

1st bit = 01
2nd bit = 02
3rd bit = 04
4th bit = 08
5th bit = 10
6th bit = 20
7th bit = 40
8th bit = 80

Now, see what happens when I calculate the sum of 5 first bits and compare it to the value of the sixth bit.
First five bits: 01 + 02 + 04 + 08 + 10 = 1F
Sixth bit: 20 = 1F + 1 = [First five bits] + 1

The magnitude of every Nth bit (in which N is a number) is always the sum of all bits from "1 to N-1" + 1.

2^n = 2^(n-1) + 2^(n-2) + ... + 2^1 + 2^0 + 1

For example for n = 5.
2^5 = 2^4 + 2^3 + 2^2 + 2^1 + 2^0 + 1
32 = 16 + 8 + 4 + 2 + 1 + 1

This leads to 8 bits being able to form one byte in exactly one way.
For example, AD.

AD = 80 + 2D = 80 + 20 + D = 80 + 20 + 8 + 5 = 80 + 20 + 8 + 4 + 1 (80 20 08 04 01).

Here, you can see that in a byte with the value of AD, the eight bit (80), sixth bit (20), fourth bit (08), third bit (04) and first bit (01) are set (1).
Seventh bit, fifth bit, and second bit are unset (0).

If you assumed that the seventh bit would be set in AD for instance, that would mean 40 would be part of it. In that case, AD = 40 + 6D = 40 + 40 + 2D.

This would lead into seventh bit being part of a byte (AD) twice which isn't real. And therefore, AD can be formed exactly in one way of its 8 bits (like explained above).

If you wanted to write AD in bit form, that would be:
10101101 (because eigth bit is 1, seventh 0, sixth 1, fifth 0, fourth 1, third 1, second 0 and first 1).

This is pretty much all the knowledge you need to play with 8-bit values (="1-byte values").

Bit Number example

In Pokemon Gold and Silver, the data of bit numbers (or flags) is stored starting at $D7B7 in RAM. Bit numbers from 0000 to 0700 are stored in D7B7, 0800 to 0F00 in D7B8, 1000 to 1700 in D7B9 and so on...
Where would bit number 3B06 be stored then?

3B06 --> 0x63B
0x63B / 0x8 = 0xC7
0xD7B7 + 0xC7 = 0xD87E

So, bit number 3B06 is part of byte $D87E in ram. The fist bit in that byte is 3806, second is 3906, third is 3A06 and so this bit is the fourth one in it, 3B06. This means that by setting the value of bit number 3B06 from 0 to 1, the byte in D87E is increased by 08. In similar way, by setting this bit value from 1 to 0, that byte value is decreased by 08.

Higher and lower nybbles

The first four and the remaining four bits in a byte have a lot in common. The highest (from fifth and eight) bits of a byte are called the higher nybble and the lowest four bits (from first to fourth) the lower nybble. This is because the highest four bits have a 10 times "stronger magnitude" to the byte than the lowest four bits. The higher nybble (80, 40, 20 and 10) sums up to F0 and lower nybble (8, 4, 2, 1) to F. And the sum of both can be as big as F0 + F = FF.

2-byte values

Gameboy is a system that uses both 1-byte and 2-byte registers for storing data. 2-byte values are called words and as bits, they consists of 16 bits. As you can assume, these can get all the values from 0000 to FFFF (2^16=65536 different choices).

Increasing and decreasing

Let's assume that our processor does the following; store the 8-bit value in D100 into some register, sum something to this register and place the result back to D100.
If for example, 7B was written in D100 and we used a command set for loading that byte into our register, increasing the value in that register by 23, and putting the result back to D100, this is what would happen:

9E would be written in D100 afterwards (because 0x7B + 0x23 = 0x9E)

But, if we used this command set for adding BE to this value in D100 instead:
39 would be written in D100 afterwards. (0x7B + 0xBE = 0x139)

Now we are increasing an 8-bit value with another 8-bit value and this leads into the system "ignoring" how the value is bigger than 0xFF.

Same works while decreasing a 8-bit value with another:

0x13 - 0x27 = -20 = 236 = EC

If we did have (in the upper example), a 16-bit value 00 7B which was increased by BE, the result written in D100 would be 01 39 though.

This pretty much sums up everything you need to know about bit and byte calculations. Hopefully, the explanations above helped!
My Rom Hack

Fixing bugs in a ROM hack
CP of encountered pokemon in GO

Learn how to hack GB/C games:

Check my GameBoy/Color hacking videos in Youtube
-The video set uses Pokemon Silver (U) rom for demonstrations
Reply With Quote