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
$0000 to $7FFF
$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.)
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)
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)
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
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 code bits are: Half Carry (H), Negative (N), Zero (Z), Overflow (V) and
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.
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 (?)