A few people out there have expressed an interest in learning machine code. And after all, if you want to write successful games, demos or utilities it is the best language to learn, albeit a bit unfriendly. The main problem with machine code is its simplicity. There, I bet that confused you a bit eh? What I mean is that almost anything can be done in a single BASIC command can take a bit more work in machine language but at a greatly increased speed.
Right, that's the intro over with so lets start looking at some commands. The first one I've decided to explain is RTS. RTS is short for ReTurn from Subroutine and its job in life is just like the BASIC return command. So why am I explaining it first? Well, if you just use it without subroutines it also acts like the end command and for the purposes of this course we will be using RTS to finish our code. So why does it have such a short name? That's due to the fact that all assembly language commands are only three letters long!
Now, if you were to just put the command RTS into an assembler and try to run it all that would happen is the "READY." message would come up. Dull, huh? For the next bit I need to explain a bit about the workings of the C64; imagine in your mind for a moment a long line of little boxes and that each box has a number on it from 0 to 65,535. A good example is box number 1,024 which controls the character at the top left of the screen. If you type POKE1024,1 and press return the letter A appears at the top left of the C64's display over whatever happened to be there. All of these boxes can hold a number from 0 to 255 (a byte). In the same way, box 53,280 controls the border colour of the screen so for example POKE53280,4 will put colour four into the border making it go purple.
But to do this in machine code is a little more complex. First off, all numbers are stored in hex, which is base 16. We all count in base 10 (mainly due to that being the number of fingers most of us have to count with) but base 16 is a little more tricky. You count to 9 as normal, but instead of saying 10 you use the letter A. Similarly you would use B to represent 11, C for 12 and so on until F (which is 15) when you would finally use 10 (pronounced "one zero" or "one oh"). But in hex 10 is 16 which would be incredibly confusing so from here on any hex number will have a dollar sign in front of it to say which base its in, for example $64.
So why do we have to use hex? The benefits will become apparent later on but as it's a good habit to think in hex we will start now to get everybody used to the idea and move on to our next two commands, which are Load Decimal Accumulator, or LDA for short, and STore Accumulator, STA to its friends. LDA is machine code's equivalent of a cross between the LET and PEEK commands, so LDA #$04 is the same as LET A=4. But LDA can also be used for reading the contents of those little memory boxes we discussed earlier, so if we were to use LDA $C000 we would be putting whatever was in location $C000 (box 49,152) into A. The use of the # tells our C64 that we are giving it a direct number to put into A and without the # the C64 will read what is in box 4 in the memory instead.
STA is the reverse, it can put whatever is in A back into a memory box. So STA $0400 will put whatever A contains into box $0400 (or 1,024, which is the top left of the screen remember?). A good example would be:
Basically this is the same as the "POKE53280,4" command we saw earlier and shows you what I meant by the simplicity. One simple BASIC command takes two in machine code for this particular job and each step has to be followed. Now an example of the second version of LDA:
Now this is slightly different. The first command reads from 53,281 (the screen colour, which is normally dark blue) and then the second puts that colour into 53,280 (the border colour again) so basically this will turn the border the same colour as the screen! So this is the same as POKE53280,PEEK(53281).
BASIC programmers will be wondering why we are always using A and not another letter for the variable. The reason is that A is not just a variable in this context, its the Accumulator. But we do have two other letters available and they are X and Y, known technically as the X and Y registers. Both can be used in a similar way to A in that:
Will do the same thing as the first example and replacing LDX with LDY and STX with STY will also work. The X and Y do have a couple of different features which will be covered in detail later, but one incredibly useful thing they can do is add or subtract 1 from their contents in a flash! This trick is done with the INX and DEX commands for the X register and INY and DEY for the Y. So how do we use them? Time for another example methinks:
This looks similar to the previous example, but the result of running it would be to make the border turn cyan! What actually happens is that first X is given the number 4 to look after. Then we tell it to go down by 1 with the DEX command leaving it with 3. Finally X is told to put it's number into the border colour but because it only holds a 3 now the colour is different. I bet you can't guess which colour 3 makes!
INX will have the reverse effect to DEX so replacing one with the other in the above example will cause X to end up holding a 5 so this time the border would be dark green. The Y register is exactly the same, so replacing all of the references to X with Y in the example will still work and produce the exact same result.
That's all for this first installment, but if you want to head on to the next part I'll show you what to do with an accumulator, two registers and an old washing up liquid bottle. If you have any questions about this article or machine code, contact me and I'll do the business with the shooters. Erm, try to help. Now you can go on to the next installment.