So, first off, hexadecimal is not nearly as old as binary, it's only about as old as 8-Bit computers like the Master System, though as far as I know nobody is certain who exactly created it. Back in the old days of room computers, programmers had to work with small groupings of bits (usually three) in order to figure things out, but as things got more complicated with bytes and words coming into the picture this method was time consuming since 0s and 1s start to get confusing when there's enough of them. Thus, let's look at binary as basically the longhand a programmer can use. Hexadecimal, by contrast, is essentially a short hand version of binary, but instead of using two symbols to represent all numbers, it uses sixteen, so it's a Base-16 system, and it worked quite well to solve this problem. Thus, a byte in binary is represented with eight symbols, as you saw in the first part of our guide. But in hexadecimal, a byte is represented with only two symbols. A lot easier, isn't it? Words then, which I'm sure you remember consist of two bytes, are represented with only four symbols instead of the whopping sixteen you'd have to use in binary. So, to reiterate, hexadecimal just makes basic programming code easier to read. Easier, that is, if you know what the symbols mean.
But it's really not that difficult. See, as mentioned in our first section, our numeral system (1 2 3 4...) is a Base-10 system, everything is represented with ten symbols. Always keep that in your head, 1 2 3 4 and so forth are technically symbols, we're just so accustomed to them in math that we don't even think about it. So hexadecimal was meant to represent binay in a simpler format to save time, but the problem is that when you get to 9, starting from 0 so that 9 is actually representing "10," what do you do to get up to 16? The problem for Base-10 is that to do that, you have to combine the first ten symbols to get anywhere, and much larger numbers can be pretty intense, though since Base-10 is such a part of mathematics, it's drilled into our heads from an early age and becomes automatic. So to get past the mess of binary, hexadecimal put everything into a set of sixteen different symbols. So what happens after 9? Simple, just use some letters.
So all you do when you get to 11 is use A, B for 12, and so on. It's quite easy. Or is it? Let's check out this:
Hmmm, what is that? Well, the first problem you need to be aware of is that, obviously, hexadecimal can look a lot like the regular Base-10 system we use all the time. What you have up there is not 37, but 55. 55? Where in the hell does that come from? One important thing we need to get out of the way is something you may have noticed in programming code if you ever took a look. Hexadecimal is marked off from Base-10 with another symbol.
So, properly, what was written up there should be written thus:
Whenever you see $ in programming code, it's indicating to you that the following representation is in hexadecimal. This is much easier to pick out when you have something like 3AB2, but when it's all numbers they decided to put a symbol in front of it to indicate hexadecimal so no one got confused. Please keep in mind that $ means nothing. It imparts no additional value to the representation that follows, it merely indicates hexadecimal, that's it. So you don't really need to worry about it at all, save to pick out where it is. Sometimes you may see $ written as 0x, but this is a rather newer method. $ is older, and was in fact the symbol used in the 8-Bit era, so that's all you need to know. Just be aware that if you happen to see 0x, or want to write your programs with it, it just means 'a hexadecimal representation is next' and nothing more. So, sure, you can pick out the representations now, but how do you decode them?
That's how. You can go much higher than that, but remember, we're only working with bytes and words here, so we don't need to go higher than four positions because four positions represents, in totality, one word. So all you have to do is take your hexadecimal representation, put each part of it from right to left under the numbers above, multiply each part with the number above and then add them together. Quite simple. So here, let's look at an actual hexadecimal representation and see how it's decoded.
So then you just take that representation, keeping in mind that you leave out the $ because it has no value, and put it into the chart above.
So, grab your calculator and do the math. 2 times 1 is 2, 2 times 16 is 32, F times 256 is 3840 (remember that F represents 15) and 3 times 4096 is 12288. Add them up and you get 16162. Easy. What's even cooler is that if you want to put something into hexadecimal straight from binary, all you have to do is separate your binary into parts of four (remember those things I told you were called nibbles). Thus, let's consider a byte like this:
Just separate it into two nibbles while not continuing with powers of two for all eight bits as we did for binary, stopping at bit four for each nibble. Here, let me show you:
I put an extra space in there so you can see they're separated. At any rate, just do the same magic we did in the binary tutorial to the nibbles and what happens? Well, the four on the right yield us 9 and the four on the left also yield us 9. Thus, you quickly put this into hexadecimal, which gives us:
That's easy! Now, please, for the love of Alex Kidd, keep in mind that the number you see there, 99, is not what you'll get if you go through the binary calculations we did the last time. If you did that, you'd actually get 153. What I've just shown you here enables you to convert a binary number into a hexadecimal representation and then back again. Don't forget that. This just gives you a method for quickly decoding items without too much trouble. But there's one more important thing you need to see. Check this out:
It's no trick, I've obviously added some 1s in the nibbles there. So, what do you get? Let's see:
Hey, Stan, wait a minute, shouldn't that be $DB ? No and yes. Here's another little feature that will be important to our purposes much later. As yet another complication to our overall goal, programmers back in the day had little arguments about what was the best way to organize data. Ever wonder why languages such as Chinese and Arabic are written right to left? Why is English left to right? Well, this is one of those issues. You see, there is a little part of programming called endianness. What? Interestingly, this term comes from Gulliver's Travels where a civil war breaks out due to the Lilliputs arguing over which side of the egg was better to break first, the big or little END. Thus, endianness. But what is endianness? Well, turns out, we can't get away from the past, and programmer Danile Cohen referenced this issue in the early days of 8-Bit programming to describe a then current argument (one that actually still fires up from time to time between geeks). Just like we have languages, computers have languages, remember? And just like English is left to right and Chinese is right to left, so too is programming code. It all depends on the type of endian a computer is, either big endian or little endian.
There's no need at all to go over this in detail, suffice to say that, though there are arguments as to which is better and why, if you have a computer that's big endian, data is written starting from the least significant part first. For our purposes, we'll be working with bytes, bits and such, so this is usually how we'll be referencing it. The most sigificant part of a binary representation, byte, word or what have you is on the left. So big endian, if we're talking about bytes, puts that one, the most significant byte, first. Thus, you can write the hexadecimal representation we have up there that way, which would be this:
But, the thing is, and here you're going to get your first little taste of programming, the Sega Master System's CPU (central processing unit, that device that runs all the programs to get our games to work) is a Z-80. The Z-80 is little endian. What's the difference? Well, in little endian, the code is written with the least signifcant data first, which means that instead of starting from the left in the binary code, byte or what have you, you start on the right. Again, there are reasons why people thought this is better, and big endian pretty much won out in the end because it's more natural to most people, but just like Chinese and English and how to write, it all comes down to one thing, that's just the way it is, there really isn't anything that makes one better than the other. For our purposes, though, little endian is better because that's how it is for SMS assembly. Thus when you see something written in hexadecimal in code for the Master System, it's indicating the least sigificant byte first. Thus, it's better for us to write our hexadecimal representation way up there as:
Just learn to think this way and you'll be fine. So to sum all that up, endianness is simply the issue of big versus little endian, that's all. Here's an example from the Master System's actual hardware:
What you see there is the code you'll eventually be using to operate the Pause button. How? Well, again, we've yet to get there, so I'll be brief without throwing too much out at you, but essentially, in order to get pause to work, you need your program (your game is a program, remember) to stop and restart after pushing Pause, so this code enables that to happen. The question I have for you is, without me fully explaining the term yet, where is the address this code is telling the program to head to? Is it at $00 or $66? Remember, little endian, think little endian. That's right, the address is at $66, because our code up there indicates the least significant byte first, and the most significant second, so this is telling the program to head over to the address at 66 (again, don't worry, we'll explain all about addresses later). Sure, gloat a little, you've just taken another step.
So there you go, you should be pretty confident of yourself already. Programming really isn't that hard if you take it slow and allow the information to sink in. Just take a quick jaunt around the internet and look for code from anything and you'll be able to pick out hexadecimal quite easily now. You've got your first little dose of programming, though not much, but keep in mind we're going slow with this. So, that's all you need to know about hexadecimal. Keep in mind that though I've been racking your brain with various problems and such, it's quite easy to find a nice converter online for free to save yourself pulling out a calculator or pencil. But before you do that to save time, let's test your skills and see what you can pull off. Below, as before, is a worksheet where you'll be defining some terms, converting binary into hexadecimal and hexadecimal into binary. After this is, of course, the answer key, but no peeking! Once you feel confident enough, it's time to move on to the next section.