Posted on Leave a comment

key basic concepts

Are you read to program? Can you answer these questions?
Who’s mom makes the best mustard pie?


Memory locations are expressed in hexadecimal notation. While data and variables are often expressed in decimal notation.

$ indicates hex value


Each memory location is one byte and can hold only one thing. Each is individually numbered in hexadecimal. They can hold either data, or program instructions.

You’ve got 32k to work with, that’s 32768 “lockers” sequentially numbered from

Cartridge ROM:
$0000 to $7FFF

Available RAM:
$C880 to $CBFF or $C800 to $C8FF if you’d like to direct address all your RAM using double plays.

6809 built-in instructions

Locker # instruction ;for example
$1000 deca ;deca is a mnemonic for a numbered instruction.

?: is the locker # essentially a line number?
Most locker ##’s are left out for the assembler to deal with. It can count, and account for instructions that take up more than one byte. We just tell it where to start.

ORG $0000 ;tells assembler to begin putting program code in mem location $0000


user_RAM        EQU     $C880 ;"EQU

EQU simply means equals. In this example, user_RAM is now a defined constant.


Registers are Vecto’s pockets. When data are in lockers, you can’t manipulate them, but once inside your pockets, you can play pool.

A,B,D,X,Y,U,S,PC,DP and CC

A = 1 byte, general-purpose register
B = 1 byte, general-purpose register
D = 2 byte combo of A & B
X & Y, both 2 byte registers used as pointers for for indexed-mode instructions
U & S, stack pointers
PC = program counter
DP = double play for direct addressing
CC = condition code (0, negative, carry, or borrow.)

Some Instructions

LD = load
LDA means load a value into register A
Putting the number “3” in register A would be done thusly: LDA #3

ST = store
STA $C880 means store contents of register A into mem loc $C880

DECA decreases the value of Reg A by 1
INCA increases Reg A by 1
These only work directly on registers A and B, in so-called “inherent” addressing mode.”

Addressing modes for instruction data handling

(alternate targets for the instruction)

  • Inherent (self-contained and takes no further arguments)
  • Immediate (target of the instruction is an actual value that will follow the instruction immediately)
  • Extended (means target is a memory location)
  • Direct (uses a 1 byte shortcut)
  • Indexed

Addressing mode examples:

LDA #$00 = immediate (loads value 0 into register A)

LDA $C880 = extended (loads contents of locker $C880 into register A)

DECA = inherent (decreases the A register by 1)

LDA #$C8
LDA $80

the above code demonstrates the use of direct mode. By transferring the memory location prefix $C8 into double play mode (DP,) LDA$80 saves two strokes and is equivalent to LDA $C880.

Program counter flow-altering instructions

  • BCC
  • BCS
  • BEQ
  • BGE
  • BGT
  • BHI
  • BHS
  • BLE
  • BLO
  • BLS
  • BLT
  • BMI
  • BNE
  • BPL
  • BRA
  • BRN
  • BSR
  • BVC
  • BVS
  • JMP
  • JSR

JMP is jump. BRA is branch. Both are unconditional jumps. BRA is preferred when possible because it saves 1byte (jump takes 3, branch takes 2) but BRA only works for locations 127 bytes ahead or behind.

My gut is telling me to always use JMP because as the program expands locations close to the 127 limit may later get pushed beyond that 127. I would save changing JMP to BRA for final code optimization if the finished .bin maxes out 32k.

JSR = “jump to subroutine.”
BSR = “branch to subroutine.” (has same 127 byte ‘ahead or behind’ limit as BRA)
RTS = “return from subroutine.”

All the remaining program counter manoeuvre’s are conditional.

Condition codes

Condition code bits are:  Half Carry (H), Negative (N), Zero (Z), Overflow (V) and
Carry (C).

BEQ = Branch on equal
BNE = Branch if NOT EQUAL

Relative vs. Absolute
BRA, BEQ, and anything that starts with “B” or “LB” for long branch is RELATIVELY positioned while JMP and JSR are ABSOLUTEly positioned.

The number of bytes to jump is determined at the time of assembly.

Weirdness alert!

You cannot branch (BRA) and jump (JMP) to the same labeled address within the same program. Chose one or the other but don’t mix. The assembler can’t deal. Chris T saved you from a mindless troubleshooting nightmare with that tip.


Here are Chris’s instructions for performing a loop 5 times.

loop_variable EQU $C880 ;Create a variable for looping
LDA #$05 ;Initialise our loop
STA loop_variable ;variable with a value of 5
loop_start: ;This is the label at the start of the loop
LDA $C880 ;These are the instructions we want to repeat 5 times
STA $C881 ;These are the instructions we want to repeat 5 times
DEC loop_variable ;Subtract the loop_variable by 1
BNE loop_start ;If the loop variable is not Zero, jump to loop_start

I’m guessing line 2 doesn’t need the dollar sign and it should really be LDA #05 (?)