Instructions (Mnemonics)

Next we will finally be discussing the machine language instructions. To make this as clear as possible I have constructed an instruction set that shows the fields required for each command. Also we will begin to start writing some code soon, testing the statements, using VICE to execute the code, yet using the CBM Prg Studio Debugger tool to review our flags, and data received back from the programs. Along the way we will eventually we writing some really cool programs, demos (rasters), sprite examples, graphic modes, raster interrupt timers that could eventually evolve into a small demo. However, that is much further down the road.

Note: The author of this website can receive a compensation for promoting, reviewing, or recommending products to viewers.

The programs will start out small so that you can easily digest within your learning curve and they will get larger as our knowledge grows. I am also trying not to introduce instructions until they have been reviewed. As an example, you won’t see a sta until we have covered the lda mnemonic first. This will gradually allow you to build upon your own experience as you start adding in new statements as you progress through this tutorial.

As we begin to evaluate the instruction set I want to make an important point. For each section I have included all of the known instructions I found according to my research. Also you may notice that in some sections I don’t review all of them. This is because I am trying to introduce them in some doses and then explain more advanced parts (with code) later. You have to eat your baby food before you can consume a real adult intake. Also if you look at the right navigation panel in Word, I have created headers for the main instructions so you can easily click on that part to visit the instructions, examples, and code there.

I will do my best to cover the instructions as we start reviewing them. However, some may be covered much later as we discover other instructions that can supplement them.

I plan to eventually introduce this Word document as a download on my website for email subscribers. This helps build my list and gives you the content you are looking for.

LDA (Load the Accumulator with Memory)

LDA

*= Add 1 when page boundary is crossed.

Definition: Immediate – Contains a number between 0 – 255 (also known as the byte). You may also hear the term “immediate addressing” in your journey.

LDA (Load the accumulator using Immediate Mode with the value specified)

This will create a value in the accumulator that is used to hold information. It does not alter memory, but can be used with other instructions to pass data to other instructions and memory locations.

The shortened word is LOAD A. This means that accumulator register A is to be loaded with a byte. The operand below is #$01. The hashmark (#) is used to show the addressing method that is to be used (also known as ‘immediate addressing’ (to be discussed much later).

Example:             lda #$01               ; Put a 1 in the accumulator – A = 1 (0-255)

The value after the # (immediate – or “hash sign”) is called the Operand.

Basic:     (using the variable A for accumulator)

A = 1

Definition:  Absolute – Contains a number between 0-65535, which are 16-bit numbers. The register is loaded with the contents of a particular memory location.

Example:             lda $33c                ; Load the accumulator with the value found in 828 (known as the absolute address)

LDA Operand, X

Definition: Operand – The book Introducing Commodore 64 Machine code describes that as ‘the part of the assembly language that specifies what is to be done’.

According to Jim Butterfield’s book Machine Language for the Commodore 64 and other Commodore computers, load (LDA) is used as a copying action. If we load A (LDA) from address $2345 we are essentially making a copy of the contents of hex 2345 into A, but 2345 still contains its previous value. Similarly, if we store Y into $3456, we are storing a copy of the contents of Y into that address. Y does not change.

The 650x has no way of moving information directly from one memory address to another. Thus, this information must passed via A, X, or Y. It is loaded from the old address, and stored into the new address.

Reference Material: Machine language for the Commodore 64 and other Commodore computers

STA (Store Accumulator in Memory)

STA

STA (Store the contents of the accumulator in the address specified)

This instruction stores the contents of the value previously contained in the accumulator (such as with an LDA) and writes it to the operand memory location.

Example:             lda #$03               ; Put a 3 in the accumulator – A = 3

                                sta $0400             ; Store the value of 3 in memory location

                                                                ; $0400 (1024), which will place a C in the

                                                                ; upper left hand corner of your screen.

                                rts

STA (Store the contents of the accumulator in the address specified)

This instruction stores the contents of the value previously contained in the accumulator (such as with an LDA) and writes it to the operand memory location.

Example:             lda #$03               ; Put a 3 in the accumulator – A = 3

                                sta $0400             ; Store the value of 3 in memory location

                                                                ; $0400 (1024), which will place a C in the

                                                                ; upper left hand corner of your screen.

                                rts

Basic:                     POKE 1024, 3

The address $0400 is sixteen bits long, and so it will take two bytes to hold the address. We place the address of the instruction, called the operand, in memory immediately behind the instruction, but there’s a twist. The last byte comes first, so that address $0400 is stored as two bytes: 00 first and then 04.

The method of storing addresses, low byte first is standard in the 650x. It seems unusual, but it’s there for a good reason. That is, the computer gets extra speed from this “backwards” address.

Reference Material: Introducing Commodore 64 Machine Code

RTS (Return from Subroutine)

RTS

Note: I felt it was important to cover the RTS statement earlier since it is used to execute out of the machine language program and into VICE Basic. This will be used when we need to look at the status registers, and the machine language monitor as a guide.

RTS is used to exit the machine language program. It is also used to return from a subroutine after a JSR, which we will be covering much later. I had to include the RTS earlier for the programs to work properly.

Definition: Implied – not a real addressing mode, but the destination is already implied within a command.  Also known as implicit.

More Program Examples

There are some more interesting instructions to come, but to keep this tutorial in the “beginner zone”, I am going to rehash some more examples with the few instructions we have learned already. This is because machine language programming can be extremely complex and I don’t want you to be overwhelmed too quickly when learning new concepts. The easiest way to understand something new is to break it down into small sections and analyze it. After all isn’t your dream to create that next coolest game? Assembly language instructions consists of a series of subroutines that are individualized into a compacted state to mesh together a much larger complete program. It’s like writing a book. You don’t start in the center or at the end. Rather you slowly progress through the sentences to build a plot that eventually tells the entire story. So for now we will change up the program a little to keep in basic.

So returning to CBM Prg Studio we are doing to change the program to change the color of the Commodore 64’s border. As usual, the LDA will store the value in memory and the STA will index the Commodore 64’s memory map to look at the address listed there. In this case we will be using memory location $d020 (53280) which is where the border subroutine is stored. We will be discussing the microchip later that manages this area, which is called VIC (Video Interface Chip) that controls the Commodore 64’s graphics.

As usual we have our program example in CBM Prg Studio

Example:

lda #$07               ; Put a 7 in the accumulator – A = 7

sta $0400             ; Store the value of 7 in memory location

$d020 (53280), which changes the border to yellow

rts

Basic:

A = 7

POKE 53280, 7

CBM Prg Studio

Now since we are finally using the tool VICE C64 emulator you will need to be familiar with a Basic instruction that will run the program. This is called SYS. It stands for SYSTEM and is used to execute a machine language program in memory at a specific memory address. In the example for our program we are running the program stored in memory location $1000 (4096), which is a safe area to store a program that doesn’t interfer with other programs resident with the CBM Prg Studio compiler.

Output example of the program

CBM Prg Studio

Feel free to change the value after LDA to any value from 0 up to 255 ($00 – $ff). See what type of colors you can come up with. Later we will be reviewing the standard color set of the Commodore 64.

The next thing we are doing to do is learn change to change the screen background (currently set to blue) by adding some new instructions to our machine language program. Memory location $d021 (53281) controls the screen background color. The new instructions are below. Also the change I made to the border color is using lda #$d to change it to a light green.

CBM Prg Studio toolbarIn order to execute the machine language program in CBM Prg Studio you will click on the right arrow at the top of the tool bar. It will instantly launch the VICE C64 emulator since it was added in the preferences section. I will show you where I did this at the exit of this tutorial as an additional bonus.

Once VICE C64 opens you can now interact with it as if you were sitting in front of a physical Commodore 64 keyboard while looking at a monitor screen. You are essentially operating in Basic in this mode, but we can access machine language with the SYS instruction as previously learned. Also when you want to interact with a window whether it is CBM Prg Studio or VICE C64, be sure to have clicked in that window first.

Example:

lda #$d               ; Put a 13 in the accumulator – A = 13

sta $d020             ; Store the value of 13 in memory location

$d020 (53280), which changes the border to light green

lda #$00

sta $d021             ; Store the value of 0 in memory location

$d021 (53281), which changes the screen to black

rts

Basic:

POKE 53280, 7

POKE 53281,0

CBM Prg Studio

To have further fun with this program, we are now going to modify it to add some new instructions that we have been using (LDA, STA) to store values in memory and look at them with the Basic PRINT command. Enter the program below to date.

Therefore we will be writing values into memory locations $033c (828) and $033d (829). As usual these are safe areas to store small programs or data into. When we learn about sprite graphics later you will see how they can be used to store data for a character (for example a sprite seen in Ghostbusters). For now though we are using this example to show how you can see a reflection of the numbers in Basic. We do this by utilizing the PRINT command. So in the example below you will see ? PEEK(828), PEEK(829) with the results shown. The question mark (?) is a short cut way of telling your Commodore 64 you want to print something on the screen. The PEEK parameter will search in a specific memory location and see what value is stored there. So in this example, it looks in 828 and 829 since we utilized this in the machine language program when we used sta $033c for memory location 828 and sta $033d for memory location 829.

Example:

lda #$d               ; Put a 13 in the accumulator – A = 13

sta $d020             ; Store the value of 13 in memory location

$d020 (53280), which changes the border to light green

lda #$00

sta $d021             ; Store the value of 0 in memory location

$d021 (53281), which changes the screen to black

lda #$04               ; Put a 4 in the accumulator – A = 4

sta $033c             ; Store the value of 4 in memory location 828

lda #$05               ; Put a 5 in the accumulator – A = 5

sta $033d             ; Store the value of 5 in memory location 829

rts

Basic:

POKE 53280, 7

POKE 53281,0

POKE 828,4

POKE 829,5

CBM Prg Studio

CBM Prg Studio Debugger

CBM Prg StudioA cool feature built into CBM Prg Studio is their Debugger tool. This will produce allow you the ability to execute statements sequentially to track their stats. An example of this would be see what values are PLL (pulled) or PHA (pushed) to the stack.  It can be incremented line by line and paused/ restarted at any time.

Using this tool with another great addition called Memory Viewer, you can see the data values in a memory dump window below the address area. Also you can search by individual addresses by entering them in the textbox window and pressing the button labeled Goto. Also as you click through the values in memory toward the bottom you will see the Binary (Bin), Octagonal (Oct), Decimal (Dec), and even the Character (Char) for that memory address section.

CBM Prg StudioAfter you click on the green arrow or select the menu Debug – Run Program, you will see the status area showing the cycles being executed as it completes over each instruction. Also pay attention to the Status Register area at the top and you will see those values changing as the program encounters instructions that are flipping flags on and off.  Now go look in the Memory Viewer at address $033c and you will see the values $04 and $05 that were loaded from the accumulator and stored in the appropriate memory locations (828, 829). This is an excellent way to see what your data is doing real time.

Setting a path to the VICE C64 Emulator

As promised, I am now going to show you how to setup CBM Prg Studio to recognize the VICE C64 emulator. It should already be downloaded to your computer. Windows users can use this link to download it http://vice-emu.sourceforge.net/windows.html

Now inside of CBM Prg Studio click on the Tools menu and select Options. When the dialog box opens change the screen to point to Emulator Control by clicking that label in the left box. The area for Emulator and path is where you will tell the editor where your copy of VICE C64 is located. If you click on the Browse button you can search for it on your system. The important thing is be sure you are using the correct file. For example min shows x64.exe. The path is listed as E:BackUpCDrive2015C64WinVICE-2.4-x.86×64.exe

After that you should be good to go whenever CBM Prg Studio has either a machine language or Basic program resident in its memory.

CBM Prg Studio

C64 Machine Language

This is a great book I’ve owned for several years. It teaches you about how the bits and bytes work regarding graphics and memory. It also has a good review of the Kernal so you can start implementing your own subroutines in code for later stages. It also contains both Basic and Assembly language listings for the Commodore 64.