A$$EMBLE IT!

Chapter 2: ASSEMBLY COMMANDS

When you are writing your own programs, it would usually be the best thing to take a look at various resources, so that you can understand all these following: commands. I can explain a few of these, but not all of them.

LDX #$00 (LDX #0), LDY #$00 (LDY #0)
This command sets the starting loop, at a value of 0. This command is very useful for writing control loops in your own programs. You can change various commands for your program, by indicating LDX #nn, where nn is the number you want to start.

When you are using LDX, or LDY loops, you can start from 0 to 256, or ($00 - $FF). Easily done

LDA #$00 (LDA #0)
This command allows you to set a value. This value could be used for either raster splits, char sets, colours, RAM, etc.

STA $xxxx (STA xxxxx)
When you set values, using LDA you can build the type of RAM which are using, when entering STA. For example if you want to build a black screen, then you enter:

LDA #$00
STA $D020
STA $D021

Quite simple eh? I'm sure it is. Ha, but you can't just LDA and STA things, you can also use LDX and LDY and instead of use STA, you can use STX or STY, for example:

LDX #$00
STX $D020
STX $D021

LDY #$00
STY $D020
STY $D021
 
Let us say for example you wanted to draw a black screen, but you want a red frame. You could use LDA and STA like as the example below:

LDA #$02
STA $D020
LDA #$00
STA $D021

Or then again, you would prefer to tidy your code, by using the X,Y method, for example:

LDX #$02
LDY #$00
STX $D020
STY $D021

There, that is MORE tidy, but when you use this method. Please remember to be very careful with it, otherwise you could end up writing a typo error, which might look something like this. This will confuse the program running, and give you some weird results. There is a theory that the LDX + LDY before STX and STY could save cycles processed by the C64's hardware.

LDX #$02                       LDX #$02
LDX #$00            or         LDX #$00
STX $D020                      STX $D020
STY $D021                      STX $D021

INX , INY
These are two command that are use to increment a value which is inside a timed loop. These can also be used for continuous moving of objects, flashing, rasters, etc.

CPX #$00, CPY #$00
These are comparing loop values of a loop, which is the value of X or Y. Basically if you use 0 as start loop and want the C64 to count the loop 255 times, then we CPX or CPY the limit. I'll show you how to use these later on :o)

BNE $xxxx
This command is used in a loop. For example, compare a value and if it does not match, go to the looping command. For example:

      LDX #$00                                LDY #$00
LOOP  INC VALUE                          LOOP INC VALUE
      INX                    OR               INY
      CPX #$FF                                CPY #$FF
      BNE LOOP                                BNE LOOP

Easy!

INC $xxxx or INC VALUE
The INC command is used to increment a value. For example, this command can be used for creating your own sprite movements, timers, etc.

DEC $xxxx or DEC VALUE
DEC is opposite to INC. Instead of incrementing a value, this command decrements a value. Yet again it can be used for practically the same as with INC, but goes the opposite way :o)

BCC & BCS
BCC & BCS are similar to the BNE command, but these are more special. Many C64 programs use BCC and BCS for their programs, I.E. some nice little game I made in the past, that use collision detection with an enemy and player, I used the following command:

                         LDX #$00
LOOP            LDA ENEMYPOS+$00,x
                CMP COLLISION
                BCC NO_COLLISION
                CMP COLLISION+$02
                BCS NO_COLLISION
                LDA ENEMYPOS+$01,x
                CMP COLLISION+$03
                BCC NO_COLLISION
                CMP COLLISION+$04
                BCS NO_COLLISION
                INC $D020
                RTS

NO_COLLISION    INX
                INX
                CPX #$10
                BNE LOOP

Pretty simple, but we will take a look at this when we start a simple little two player game project.

CMP #$00 (or CMP #0)
The command CMP #$nn compares a value that IS/NOT in a loop. For example you can compare values for positions of sprite movements and set the stopping values rather than just have them continuously looping :o)

JSR $xxxx, JSR ROUTINE
The JSR routine is always used inside or outside an Interrupt ReQuest (IRQ) flag, which jumps to a routine, but allows you to continue your programming. For example:

                   LDX #$00
        JSR $1048

        JSR COLOURWASH
        JSR ANIMATE
        JSR $1021 ;Play music

JMP $xxxx, JMP ROUTINE
JMP is similar to JSR, but this time it jumps to a routine that you want. For example, freezing your own program

HOLD JMP HOLD

There are also a couple of special JMP routines, which are JMP $EA81 and JMP $EA31, these are of course used in IRQ routines

CLC
ADC #$00 or (ADC #0)
Calculate and add a value

SEC
SBC #$00 or (SBC #0)
Reverse calculate and subtract a value

BEQ STATEMENT
Similar BNE, BCC and BCS, but a bit different. These are mainly used in loops, to default values of pointers.

SEI
SEI turns off an IRQ interrupt flag, when a loop is inside the program

CLI
Clears registers and allows the programmer to insert additional commands, which they cannot use inside an IRQ loop!

PLA
PHA
RTI
These are special commands.

TAX or TAY
Mainly used to control scrolling types, initialize everything, for example, music!

LDA #$00
TAX
TAY
JSR $1000 ;Initialize DMC 4 tune

.BYTE (or .BYT)
Data tables for animation, colours, etc.

.TEXT (or .TXT)
Data tables for creating your own text

<>There are many other commands, but the commands (PLA, PHA, RTI, SED, CLD) that I don't use, and they're for more advanced programmers.
 

Writing your first program:

We are going to write our first program, which is just something small and simple. This program shows you how to create your own flashing border, while asking for the user to press the space bar. After the space bar is pressed the program will exit. So load up your assembler and type in the following listing, then assemble and run.

METHOD 1:

;===================
;RAINBOW COLOURS
;===================

               * = $0900 ;Jump start for code
               SEI      ;CLEAR IRQ
LOOP           INC $D020; INCREMENT BORDER
               LDA $DC01; CHECK BUFFER
               CMP #$EF ; IS SPACE PRESSED?
               BNE LOOP ; IF NOT THEN JUMP TO LOOP
               RTS      ; IF SPACE IS PRESSED THEN END

RESULT:


Can you see how easy it is to create your own short program? Now all you need to do is assemble the program and run it. Guess what? You'll see a flashing border. The border will continue to flash until you press space. Then the program will finish. Well why does the program continue flashing, before SPACEBAR is pressed? Well, that's easy, because the program is inside a control loop, which continues to loop until the value #$EF is found, and then the C64 stops running the program, as the program tells it to do so. Now why not try deleting LDA $DC01, CMP #$EF and BNE LOOP into:

METHOD 2:

;===================
;RAINBOW COLOURS
;===================

               * = $0900 ;Jump start for code
                SEI                ;CLEAR IRQ
LOOP            INC $D020   ; INCREMENT BORDER
                LDA $DC01 ; CHECK SPACEBAR
                LSR              ; If SPACEBAR IS NOT
                LSR              ; PRESSED THEN JUMP
                LSR              ; TO THE LOOP!
                LSR
                LSR
                BCS LOOP
                RTS

Not much of a difference there, but this is also checking for a button on joystick port 1. Yes, that's right FIRE BUTTON. The spacebar will still work.

I would prefer to use method 1, in order of processing the code. This is because it is shorter compared to method 2. Shorter routines can compress the program, which you write. It also saves the amount of memory that has been used in an assembler.

Using X+Y loops

 As you noticed just a while ago. I gave you an example program that allows you to flash the colour borders, but now, I'm going to show you how you can EXPAND colour sizes. Here is what we'll do. We shall use an LDX prompt and also an LDY prompt (for X and Y loops). We shall still use INC $D020 and INC $D021 and the pressing spacebar method, but this is just a little taster of what we have in store for this section :o)

;==================
;FLASHING BORDERS
;USING X & Y LOOPS
;==================
                  *=$0900                     <- you should know what this routine does
                  SEI                             <- and this one
MAINLOOP          LDX #$00              ;Set 'X' as 0
LOOPX             LDY #$00              ;Set 'Y' as 0
LOOPY             INC $D020            ;Flashy border
                  INY                         ;Increment Y
                  CPY #$77               ; Is 'Y' equal to #$77
                  BNE LOOPY         ; If not then Y=Y+1, goto LOOPY
                  INX                        ; Increment X
                  CPX #$77               ; Is 'X' equal to #$77
                  BNE LOOPX         ;If not then X=X+1, goto LOOPX
                  LDA $DC01           ;Load Spacebar command
                  CMP #$EF             ;Is spacebar pressed
                  BNE MAINLOOP ; If not then jump to the MAINLOOP prompt
                  RTS                         ; else END program operation

You will notice that there wont be much of a difference in the flashing borders. However, we could try something different. Here is what to do.

Underneath RTS, build your own colour table. Include the label COLOURS. You could try the following:

COLOURS
                        .BYTE $00,$06,$0E,$03
                        .BYTE $03,$0E,$06,$00

Now let's try a little experiment shall we?

Where we have INC $D020, replace this with LDA COLOURS,X and then add STA $D020. We're not finished there yet. In order to read the amount of colours that are in the colour table, the next thing for you to do is change CPY #$77 to CPY #$27 and then change CPX #$77 into CPX #$08. Now let's test it ;o)

RESULT:


Different.

Now, why not try and change CPY #$08 and see what happens next ;o) Notice any differences? The border thins down and it scrolls something like those colour bars, which have been used on SEUCK games apart from SEUCK bars go upwards instead of downwards.

Thinning colour bars, etc is plain easy to handle, but when $D012 is involved, things change.

The borders look a mess, as they are flickering so what should be done now is some minor adjustment to the flickers. All we do is add NOP, a few times, until the borders are nice and straight. Let's try it. Erm, no, as not much effort would be put into it. Maybe using $D012 would help. We'll look at this later on.

Next Page / Previous Page / Back to page of contents