Beginners Gaming Guide in Machine Language

Note: This book represents a smaller condensed version of the book “The Machine Language Book of the Commodore 64”. I found this much more effective to revise rather than starting from scratch as “machine language” is a complicated subject.

Finally understand that this is a “work in progress” and this page will be updated over time. Eventually it will include the Simple Game I am working on through my Facebook channel, that is seen below. You will control a sprite that can move through several different screens.

Probably some of the best advice I can give to any absolute beginner wanting to learn assembly language and write their first demo or game is that its going to take some time to master this. You will not learn this in one day or a month. However, if you stick with basic concepts, you will get better over time. My ultimate goal is to break it down to a “excuse me” third grade level so you can better digest the flow of learning it.

Also it is recommended to have at least some general knowledge of Basic and how the computer memory works to really grasp the essentials of writing good code.

To start off just know that the Commodore 64 and other VIC computers have no knowledge of Basic programming at all. Everything secretly exists in the strange world of “machine language” to your system. All it really understands is binary (0’s and 1’s).

However, the developers of the earliest Commodore (PET) computers wanted to make a computer friendly to use, so they created specifically an “operating system” that your computer uses to understand simple instructions as is common in Basic.

If you are a beginner to Basic programming stick with the first few chapters, otherwise feel free to skip past these. My goal is to write an eBook that makes speaks directly with your level of expertise (as a beginner or intermediate Assembly language Developer).

Basic has the ability to convert the machine language insturctions it receives into commands and statements that help you build a “computer program”. Basic utilizes an “interpreter” that actually does a serarch through a command table for any of the commands one would use to create a Basic program with. There are also several other rules used to help build a token list that is used to create the environment that allows for such programming, but to keep the tutorial simple, I wont go into heavy detail on that.

To be honest though you can’t really write a good demo or game in Commodore Basic. You would have better success doing this on an Atari computer since their interpreter communicates more effectively with machine language, and they have a video chip that is effective with graphics programming.

So most users transition from Basic to Assembly language (Machine Language) since it can run instructions must faster than a Basic program since Basic is using a machine language interpreter that is delayed when the computer has to search through a command table, perform taks, among many other things just to get a Basic program working properly.

Basic is the best foundation on which to begin your journey into assembly language programming.

Granted that learning assembly language will require learning a whole new set of instructions, but in time you will see hopefully the crossover from Basic to assembly language.

Going forward, I will replace “assembly language” to “machine language” to cater to old time users since that is how the computer really understands instructions and information in general.

Variables

A variable is essentially tied to Basic program to handle things like counters, x/y positions, memory registers in the very least. If you understand this then writing your first “machine language” program shouldn’t prove too difficult.

We will explore memory more effectively so you can begin writing some simple “start up” programs.

Processor

More than likely your Commodore computer contains a 6510 micoprocessor that uses a set of registers to manage its operations.

The 6510 can only understand digital information between conditions. This is known as “binary”. Essentially binary consists of either a one (“on”) or zero (“off”). The original computer systems consisted of flipping switching on or off to put information into the registers.

Binary (also known as “bits”) can be grouped together to make up a byte. The 6510 registers use 8 bits to create a byte.

(Example of bit number/contents).

The top row has numbers from zero to seven. The bits under that represent the byte used by the 6510 microprocessor.

Since the byte actually is a number, its important to also learn how the math works behind this. This is based on the decimal numbering system. Look at the example below that shows how to calculate a decimal number uses just the binary bits you learned about, which uses powers of two going from right to left across the bits.

Hexadecimal Numbers

The total result of a byte (8 bits) can never exceed 255. It was realized earlier during the introduction of machine language programming, that using binary numbers to achieve such calculations was complicated. So a better system was soon devised known as “hexadecimal”.

I won’t go into complete explanation to keep this tutorial “brief”, but hexadecimal values use the digits 0 through 9 and the letters A-F to replace numbers from 10 through 15. I’ve also resorted just to using a decimal to hex converter to make it easier, but you are welcome to explore hex further.

A hexadecimal number uses a dollar sign in front to distinguish between decimal. A binary number uses a percent sign likewise.

The 6510 chip has 6 registers. Five are 8 bit and the 6th one is a 16-bit register.

Accumulator

This is the primary register used when writing “machine language” programs. It handles the math, logical, and conditional (comparison) instructions.

X Register

It’s used with the accumulator when working with tables. It often used as a counter or even a pointer to table elements, which why you may also hear the word “index register” to represent it.

Y Register

It’s very identical to the X register and they are often bundled together when writing programs.

Program Counter

Known as a 16-bit register, used as a pointer to memory locations that handle the instructions you would use to build a program with. Although you can relocate the memory pointer of this register, you don’t have control over the contents of it.

Stack Pointer

Uses an memory section known as the “stack” that can be used inside of subroutines and the saving of data to be retrieved inside a program.

Processor Status Register

Handles the last executed instruction results. Primarily it is used for the decisions and conditional branch instructions in a program.

There are 7 of the 8 bits in this register that are used as flags. These can be examined to learn about the operation of the registers checking on their current “status” (hence the name). A flag can be either set (1) or cleared (0).

bit position 7 6 5 4 3 2 1 0
flag type N V – B D I Z C

The letters for the registers are explained as follows:

C – Carry. Contains the carry from additions, and can be set is the number exceeds 255.

Z – Zero. It is set when the result of an operation is zero.

I – Interrupt Disable. Used whenever an interrupt is used in a program (for more advanced users)

D – Decimal. Lets the accumulator know if arithmetic is using decimal mode.

B – Break. Signals that the program was halted (using the BRK instruction).

V – Overflow. Used when working with signed numbers and an overflow occurs.

N – Negative. It is set when a result is greater than 127 (sets bit 7) or results in a negative number (less than zero).

The 6510 needs an area to store data. Therefore using its memory allows it to manage operations of your program. This is also known as “addressing”. The CPU (Central Processing Unit: 6510) has the ability to address either 8 bits of memory (between 0-255) or even 16 bits (beyond 255). The top level of access is 2 to the power of 16 or 65536 memory locations on your Commodore computer.

Just as Basic uses instructions (commands) to help build a program, machine language uses its own set of instructions (up to 256) with many of them being used more than once. However since Basic is actually just a machine language program, it should be obvious that machine language programs do not interrupt Basic commands.

To give you more confidence, although the 6510 does contain up to 256 instructions, there are actually only 56 different instructions that you will need to learn since they can be used over and over.

Machine language instructions use 8-bit binary numbers to form what are known as “mnemonic names”. Its actually an abbreviation for a simple 3 letter name.

We can finally explore some machine language instructions!

The Load Instruction
It is used to obtain data in memory and put it into three different registers as seen below.

LDA Load Accumulator
LDX Load X register
LDY Load Y register

There are also different addressing modes that inform the 6510 how to caculate an address. Lets explore these further.

1) Immediate Addressing

Example: LDA #15

Notice that the address mode uses a pound sign with a number after that. So this will read the direct result (immediate) of the number after the pound sign. This is read as “Load the accumulator with the immediate value of 15”.

In a Basic program you will see a variables such as

A=15, X=15, RE=15

In Basic you can use any two letter combination of letters, but machine language uses that instruction.

The same thing works with the X and Y registers

LDX #$0 = LDX #0 (decimal)
LDY #$7f = LDY #127 (decimal)

After instructions are entered, the program accumulator will increase by the number of those instructions. In either of the results above, the program counter will now be two places ahead in memory. Then it is ready to receive the next instructions following these two instructions (bytes).

Absolute Addressing

Used if a register needs to access a specific memory locations contents. Very similar to PEEK in Basic. Below is an example to read from a joystick. I have also included how they are seen in memory.

173, 0, 220 LDA $DC00 ; LDA 56320

Often when you are using a monitor for machine language they will be in hexadecimal (without the symbol), so let’s translate that again.

AD 00 DC LDA $DC00

Please note that the above instruction is actually accessing a 16-bit value. So to calculate this effectively we take the second leftmost digit (00) add it to the next digit going to the right (DC) and multiply it by 256. Here is how its seen calculated in memory.

Hex: $00 + $DC * $100 = $DC00
Decimal: 00 + 220 * 256 = 56320

The second digit is known as the “low-byte” (00) and the digit to the right is known as the “high-byte” (220).

Here is is as viewed in a Basic program

JY=PEEK(56320)

The next thing to examine is what action was taken on the status registers will this simple instruction. If a value was loaded into the accumulator then the zero flag would be set. If its not zero, then of course if will be cleared.

When we get into how to use a compiler (such as CBM Prg Studio or KickAss), you will then learn how to load their status registers and check the results there.

For now though just known that the LDX #0 set the zero flag register and the second operation cleared it. We also loaded a value into the X and Y registers earlier.

The next chapter will explore Zero Page Addressing.

Thanks for staying with us!