Learn Multi platform 6309 Assembly Programming... With Secret stuff!

The 6809 was pretty good... and Hitachi decided they wanted to make their own version - the 6309!

However, they decided they could do better, and added a ton of extra commands and registers to the chip!... the 6309 has an extra 2 eight bit registers, for a total of 32 bits!

Rather strangely they forgot to tell anyone, and it was much later that anyone found out about all the extra functionality!

Useful Resources
The 6309 Book

If you want to learn 6309 get the 6309 cheatsheet It contains all the 6809 and 6309 opcodes.

We'll be using Macroassembler AS for our assembly in these tutorials... VASM is an assembler which supports rarer CPU's like 6309 and 65816 and many more, and also supports multiple syntax schemes...

You can get the source and documentation for AS from the official website HERE

What is the 6309 and what are 8 'bits' You can skip this if you know about binary and Hex (This is a copy of the same section in the Z80 tutorial)
The 6309 is an 8-Bit processor with a 16 bit Address bus!... it has two 8 bit accumulators, A and B, that can be combined to make up one 16 bit accumulator D (AB)
What's 8 bit... well, one 'Bit' can be 1 or 0
four bits make a Nibble (0-15)
two nibbles (8 bits) make a byte (0-255)
two bytes (16 bits) make a word (0-65535)

And what is 65535? well that's 64 kilobytes ... in computers Kilo is 1024, because four bytes is 1024 bytes
64 kilobytes is the amount of memory a basic 8-bit system can access

the 6309 is 8 bit so it's best at numbers less than 256... it can do numbers up to 65535 too more slowly... and really big numbers will be much harder to do! - we can design our game round small numbers so these limits aren't a problem.

You probably think 64 kilobytes doesn't sound much when a small game now takes 8 gigabytes, but that's 'cos modern games are sloppy, inefficient,  fat and lazy - like the basement dwelling losers who wrote them!!!
6309 code is small, fast, and super efficient - with ASM you can do things in 1k that will amaze you!

Numbers in Assembly can be represented in different ways.
A 'Nibble' (half a byte) can be represented as Binary (0000-1111) , Decimal (0-15) or  Hexadecimal (0-F)... unfortunately, you'll need to learn all three for programming!

Also a letter can be a number... Capital 'A'  is stored in the computer as number 65!

Think of Hexadecimal as being the number system invented by someone wit h 15 fingers, ABCDEF are just numbers above 9!
Decimal is just the same, it only has 1 and 0.

In this guide, Binary will shown with a % symbol... eg %11001100 ... hexadecimal will be shown with & eg.. &FF.

Assemblers will use a symbol to denote a hexadecimal number, some use $FF or #FF or even 0x, but this guide uses & - as this is how hexadecimal is represented in CPC basic
All the code in this tutorial is designed for compiling with WinApe's assembler - if you're using something else you may need to change a few things!
But remember, whatever compiler you use, while the text based source code may need to be slightly different, the compiled "BYTES' will be the same!
Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... 255
Binary 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111   11111111
Hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F   FF

Another way to think of binary is think what each digit is 'Worth' ... each digit in a number has it's own value... lets take a look at %11001100 in detail and add up it's total

Bit position 7 6 5 4 3 2 1 0
Digit Value (D) 128 64 32 16 8 4 2 1
Our number (N) 1 1 0 0 1 1 0 0
D x N 128 64 0 0 8 4 0 0
128+64+8+4= 204            So %11001100 = 204 !

If a binary number is small, it may be shown as %11 ... this is the same as %00000011
Also notice in the chart above, each bit has a number, the bit on the far right is no 0, and the far left is 7... don't worry about it now, but you will need it one day!

If you ever get confused, look at Windows Calculator, Switch to 'Programmer Mode' and  it has binary and Hexadecimal view, so you can change numbers from one form to another!
If you're an Excel fan, Look up the functions DEC2BIN and DEC2HEX... Excel has all the commands to you need to convert one thing to the other!

But wait! I said a Byte could go from 0-255 before, well what happens if you add 1 to 255? Well it overflows, and goes back to 0!...  The same happens if we add 2 to 254... if we add 2 to 255, we will end up with 1
this is actually usefull, as if we want to subtract a number, we can use this to work out what number to add to get the effect we want

Negative number -1 -2 -3 -5 -10 -20 -50 -254 -255
Equivalent Byte value 255 254 253 251 246 236 206 2 1
Equivalent Hex Byte Value FF FE FD FB F6 EC CE 2 1

All these number types can be confusing, but don't worry! Your Assembler will do the work for you!
You can type %11111111 ,  &FF , 255  or  -1  ... but the assembler knows these are all the same thing! Type whatever you prefer in your ode and the assembler will work out what that means and put the right data in the compiled code!

The 6309 Registers
Compared to the 6502, the 6309 is seriously powerful - and even gives the Z80 something to think about!

8 Bit 16 Bit 24 Bit 32 Bit Use cases
accumulator A A

8 Bit Accumulator
accumulator B B

8 Bit Accumulator
accumulator E E

accumulator F F

16-Bit Accumulator  D

A+B combined to make a 16 bit Double accumulator
16-Bit Accumulator  W E F

E+F combined to make a 16 bit Word accumulator
32-Bit Accumulator  Q A
A+B+E+F combined to make a 32 bit Quad accumulator
Condition Code Register CCR

Mode Register MD

Zero Register (fixed) 0 / Z

Transfer Value V

Fixed Value... accessible via TFR only
survives reset!
Indirect X X

Indirect Register
Indirect Y Y

Indirect Register
User Stack Pointer U

User Stack
Hardware Stack  Pointer  S

Program Counter PC

Running Command
Direct Page DP

Zero page is relocatable on 6309

    MD: 0I------FN CC: EFHINZVC

Name Meaning
Division By Zero
Illegal instruction Exception
FIRQ pushes all registers (1=on)
Native mode (1=on)
E Entire Flag Regular/Fast Interrupt flag
F FIRQ Mask Fast Interrupt Flag
H Half Carry Bit 3/4 carry for BCD
I IRQ Mask Interrupt Flag
N Negative
Z Zero
V oVerflow
C Carry

note E and F cannot be pushed with PSHS ... you must use PSHSW and PULSW (W=E+F)

The Direct page is like the 6502 Zero Page, however it does not need to be at zero!

We can load A with a value, then TFR A,DP to set the direct page... we need to tell the assembler where the direct page is, otherwise some commands may malfunction, we do this with ASSUME dpr:$xx - this is called SETDP on some assemblers

Like the 68000, the 6309 is BIG ENDIAN... this means a 16 bit pair stored to an address like $6000 will save the high byte to $6000, and the low byte to $6001

Special Memory addresses on the 6309
Unlike the 6502, The 6309 has full 16 bit Stack pointers, U and S.... the 'Zero Page' (AKA Direct Page) can also be re positioned

Like the 6502, there are a variety of 'Interrupt Vectors' with fixed addresses...
Address Vector (Address) Registers Auto-pushed onto stack
$FFF2 SWi 3 Vector
$FFF4 SWI 2 Vector
$FFF6 FIRQ Vector CC (E flag cleared)
$FFF8 IRQ Vector D,X,Y,U,DP,CC
$FFFA SWI 1 Vector D,X,Y,U,DP,CC

The 6309 Addressing Modes
The 6502 has 11 different addrssing modes... many have no comparable equivalent on the Z80

Inherent Addressing Commands that don't take a parameter ABX
Register Addressing Commands that only use register TFR A,DP
Immediate Addressing Direct Address of command ADDA #$10
ADDD #$1000
Direct Page addressing Read from DP (zero page) ADDA $10
Extended Direct addressing Read from an address ADDA $1234
Extended Indirect Addressing Read from the address specified... then get the value from that address ADDA [$1234]
Indexed Addressing Uses a 2nd setting byte - allows for Autoinc ,R
Indexed Addressing: Zero Offset Just use the address in the register LDA ,Y
Indexed Addressing: 5 bit offset -16 to +15 offset LDA -1,Y
Indexed Addressing: Constant offset from base register 8 / 16 bit offset from X,Y,U,S ... Can be negative or positive LDA 1000,Y
Indexed Addressing: Constant Offset From PC 8 / 16 bit offset from PC LDA $10,PC
Program counter relative PCR is like PC, but is calculated by the assembler ADDA label,PCR
Indirect with constant offset from base register Load from the address in the register + offset LDA [1,X]
Accumulator offset from Base register Add accumulator (A/B/D) to a X,Y,U,S (not PC) LDA B,Y
Indirect Accumulator offset from Base register Load from the address made up of a X,Y,U,S Plus the accumulator LD [B,Y]
AutoIncrement Add 1 or 2 to the register ADDA ,X+
AutoDecrement Subtract 1 or 2 from the register ADDA ,-X
Indirect AutoIncrement Load from the address in Register, then add 1 or 2 ADDA [,X+]
ADDA [,X++]
Indirect AutoDecrement Subtract 1 or 2 then Load from the address in Register ADDA [,-X]
ADDA [,--X]
Program relative Offset to PC BRA label

Saving a byte on return:

Rather than returning, if your last command is a pop, just pop the PC with your other registers:
Addresses, Numbers and Hex... 6309 notification
We'll be using VASM for our assembler, but most other 6502 assemblers use the same formats... however coming from Z80, they can be a little confusing, so lets make it clear which is which!
Prefix Example Z80 equivalent   Meaning
# #16384 16384 Decimal Number
#% #%00001111 %00001111 Binary Number
#$ #$4000 &4000 Hexadecimal number
#' #'a 'a' ascii value

12345 (16384) decimal memory address
$ $4000 (&4000) Hexadecimal memory address

Missing Commands!
Commands we don't have, but might want!
DEX/DEY/INX/INY Tfr X,D ;replace X with Y if required
DecB ;or IncB as required
Tfr D,X ;replace X with Y if required

CLC AndCC #%11111110
SEC OrCC #%00000001

Lesson 1 - Getting started with 6309
Lets learn the basics of using 6309... We'll take a look at the new registers, and some of the new commands.

The 6809 devtools
support 6309


6309 supports everything 6809 does... so we'll only cover the new stuff here!

If you don't know 6809 yet, please see these tutorials!

New Registers!
The 6809's two 8 bit registers have been doubled!

As well as the old A and B, we now have E and F!
Of course, The 16 bit D register is still made up of A+B, but we now have another 16 bit pair known as W

W is made up of E+F
All 4 8 bit registers are combined in some cases to make one 32 bit quad, known as Q

Q is made up of A+B+E+F
There are a few more weird and wonderful registers!

0 (or z in asw) is a hardwired zero, we can use it as a substitute for a regsiter, to get a zero value, or 'discard' the result of a command.

V is a 16 bit register referred to as the 'Transfer Value'. We can't set it directly like E and F, but we can move values into it. Also, strangely, it keeps its value after a reboot!

The final register is MD - the MoDe register. We can turn on bit 0 to enable Native 6309 mode, though we can use all the new commands without doing so!. Turning on native mode alters the way the interrupts work.
Here are the results.

Commands using the new registers like E and F often take an extra byte than the ones using A and B.
You should still prioritize the original registers where you can, and just use the new ones as an alternative to the zero page, or to reduce push pops.

Many of the previous maths commands can now be used with the new registers.
We can use Clear, Inc and Dec... and these now even work with the D register.

The new registers also work with ADD and SUB
Here are the results.
We have new ADDR and SUBR commands, which will add and subtract one register from/to another. The destination is on the right.

ADCR and SBCR provide similar functions, but add and subtract the carry as well

Unfortunately we dont have a 32 bit add or subtract command which works with Q, but we can use the 16 bit commands to effect a 32 bit add or subtract via the carry.
Here are the results

Lesson 2 - Shifts, Compares and logical ops
The 6309 adds lots of new commands, and adds new supported registers to old ones... lets see what we can do now!

The 6809 devtools
support 6309


Rotation and shifts
We now have 16 bit rotate and shift commands, which work with the D and W registers.

ROR and ROL shift between the 16 bits of the register, plus the carry as a 17th bit

We do not, however, have any that work with the 32 bit Q
Here are the results
We have new logical shift commands for unsigned 16 bit numbers.

We now have LSRD and LSRW

Strangely, while we have a LSLD, we do not have a LSLW, however "ADDR W,W" will add W to itself giving the same effect.
Here are the results
We have new Arithmetic shift commands for signed 16 bit numbers.

We now have ASRD and ASRW

Strangely, while we have a ASLD, we do not have a ASLW, however "ADDR W,W" will add W to itself giving the same effect.
Here are the results

Tests and compares
We have TST and CMP commands for the new 8 and 16 bit registers. These commands work the same as usual.

TST will set the Zero and Negative flags based on the contents of a register.

CMP will set the flags like a subtraction, but will not change the tested register.

Unfortunately these commands cannot work with the 32 bit Q register.
Here are the results

Logical Operations
We have some new logical operations!

EOR, AND and OR now can work with the 16 bit D register (but not the W one)

We now also have commands which work with register to register values. The first specified register will be processed with the second, and the result stored in the second register.
Here are the results
We have some new commands which perform an operation with an Immediate value and the address in a register + an offset, changing the byte at the effective address.

EIM will Eor an Immediate with Memory
AIM will And an Immediate with Memory
OIM will Or an Immediate with Memory

TIM will Test an Immediate with Memory - setting the flags like logical operation AND
Here are the results.

More Maths Operations
We have a few other useful commands which perform Bit operations

SEXW will Sign EXtend 16 bit W into a 32 bit value Q (effectively filling D with the top bit of W)

NEGD will negate the 16 bit D register - however there is no command to negate the W register.

We also have a COMplement command, which will flip the bits of a register, this works on all the 8 and 16 bit registers, but the 32 bit Q cannot be flipped in a single command
Here are the results

Lesson 3 - More new commands!
Lets take a look at the last of the new 6309 commands.

The 6809 devtools
support 6309


Push and Pull Commands
The PSH and PUL commands do not work with the new E and F registers (and by implication W)

The only way to backup and restore these registers via the stack are using the 4 new commands.

PSHSW will Push W onto the S stack.
PULSW will Pull W off the S stack.

PSHUW will Push W onto the U stack.
PULUW will Pull W off the U stack.
Here  are the results

Bulk transfer commands
The 6309 adds some impressive new bulk transfer commands... these give functions like LDIR on the Z80, or MVN on the 65816.

The TFM command allows us to transfer from one register to another, with a variety of Increment and Decrement options (4 in total)

TFM r1+,r2+ will copy W bytes from the address in r1 to the address in r2, incrementing both after each byte.

TFM r1-,r2- will copy W bytes from the address in r1 to the address in r2, decrementing both after each byte.
Here are the results!

We copied 4 bytes to the right, then 4 bytes to the left.
We have two more slightly strange options

TFM r1+,r2 will copy W bytes from the address in r1 to the address in r2, incrementing only the source after each byte

TFM r1,r2+ will copy W bytes from the address in r1 to the address in r2, incrementing only the destination after each byte

These could be usedful for transferring a block of data to, or from, a memory mapped hardware port.
Here are the results, first we transferred 89,AB,CD,EF to $7104 (leaving only EF visible)

Then we transferred 89 four times.

Multiplication and Division
We have a new 16/32 bit Multiply command! 
will multiply D by either an immediate or memory value - alas we can't multiply by the w register.

DIVQ is the opposite, this divides the 32 bit value in Q by the specified value, putting the whole number result in W, and the remainder in D

DIVD is the opposite of the original MUL command, this divides the 16 bit value in D, putting the whole number result in B and the remainder in A
Here is the results!

ASW seems to not assembly the DIVD command correctly, it seems to store the immediate value as a 16 bit value, causing the command to end up as 4 bytes, rather than the apparently correct 3.

Bit Test and Set
There are a set of special new commands for bit manipulation on the 6309:
LDBT    Load Memory Bit into Register Bit
STBT    Store value of a Register Bit into Memory

BAND    Logically AND Register Bit with Memory Bit
BOR    Logically OR Memory Bit with Register Bit
BEOR    Exclusive-OR Register Bit with Memory Bit
BITD    Bit Test Accumulator D with Memory Word Value

BIEOR    Exclusively-OR Register Bit with Inverted Memory Bit
BIOR    Logically OR Register Bit with Inverted Memory Bit

These have an odd format:

CMD Reg.Bit, Address.Bit
Where Reg and Address are the source/destination (Depending on the command), and Bit is the source and destination bit numbers (0-7)

Unfortunately, it seems they are not emulated properly - the 3 register options A,B,CC are mixed up  (I think the assembler is doing them right), so we won't be covering them in detail here.


View Options
Default Dark
Simple (Hide this menu)
Print Mode (white background)

Top Menu
***Main Menu***
Youtube channel
Introduction to Assembly (Basics for absolute beginners)
Amazon Affiliate Link
AkuSprite Editor
Dec/Bin/Hex/Oct/Ascii Table

Alt Tech
Please note: I wlll upload more content to these alt platforms based on the views they bring in

Z80 Content
***Z80 Tutorial List***
Learn Z80 Assembly (2021)
Learn Z80 Assembly (old)
Hello World
Simple Samples
Advanced Series
Multiplatform Series
Platform Specific Series
ChibiAkumas Series
Grime Z80
Z80 Downloads
Z80 Cheatsheet
DevTools kit
Z80 Platforms
Amstrad CPC
Elan Enterprise
Gameboy & Gameboy Color
Master System & GameGear
Sam Coupe
ZX Spectrum
Spectrum NEXT
Camputers Lynx

6502 Content
***6502 Tutorial List***
Learn 6502 Assembly
Advanced Series
Platform Specific Series
Hello World Series
Simple Samples
Grime 6502
6502 Cheatsheet
DevTools kit
6502 Platforms
Apple IIe
Atari 800 and 5200
Atari Lynx
BBC Micro
Commodore 64
Commodore PET
Commander x16
Super Nintendo (SNES)
Nintendo NES / Famicom
PC Engine (Turbografx-16)
Vic 20

68000 Content
***68000 Tutorial List***
Learn 68000 Assembly
Hello World Series
Platform Specific Series
Simple Samples
Grime 68000
68000 Cheatsheet
DevTools kit
68000 Platforms
Amiga 500
Atari ST
Neo Geo
Sega Genesis / Mega Drive
Sinclair QL
X68000 (Sharp x68k)

8086 Content
Learn 8086 Assembly
Platform Specific Series
Hello World Series
Simple Samples
8086 Cheatsheet
DevTools kit
8086 Platforms

ARM Content
Learn ARM Assembly
Learn ARM Thumb Assembly
Platform Specific Series
Hello World
Simple Samples
ARM Downloads
ARM Cheatsheet
DevTools kit
ARM Platforms
Gameboy Advance
Nintendo DS
Risc Os

Risc-V Content
Learn Risc-V Assembly
Risc-V Downloads
Risc-V Cheatsheet
DevTools kit

MIPS Content
Learn Risc-V Assembly
Platform Specific Series
Hello World
Simple Samples
MIPS Downloads
MIPS Cheatsheet
DevTools kit
MIPS Platforms

PDP-11 Content
Learn PDP-11 Assembly
Platform Specific Series
Simple Samples
PDP-11 Downloads
PDP-11 Cheatsheet
DevTools kit
PDP-11 Platforms

TMS9900 Content
Learn TMS9900 Assembly
Platform Specific Series
Hello World
TMS9900 Downloads
TMS9900 Cheatsheet
DevTools kit
TMS9900 Platforms
Ti 99

6809 Content
Learn 6809 Assembly
Learn 6309 Assembly
Platform Specific Series
Hello World Series
Simple Samples
6809/6309 Cheatsheet
DevTools kit
6809 Platforms
Dragon 32/Tandy Coco
Fujitsu FM7
TRS-80 Coco 3

65816 Content
Learn 65816 Assembly
Hello World
Simple Samples
65816 Cheatsheet
DevTools kit
65816 Platforms

eZ80 Content
Learn eZ80 Assembly
Platform Specific Series
eZ80 Downloads
eZ80 Cheatsheet
DevTools kit
eZ80 Platforms
Ti84 PCE

IBM370 Content
Learn IBM370 Assembly
Simple Samples
IBM370 Downloads
IBM370 Cheatsheet
DevTools kit

Super-H Content
Learn SH2 Assembly
Hello World Series
Simple Samples
SH2 Downloads
SH2 Cheatsheet
DevTools kit
SH2 Platforms

PowerPC Content
Learn PowerPC Assembly
Hello World Series
Simple Samples
PowerPC Downloads
PowerPC Cheatsheet
DevTools kit
PowerPC Platforms

Work in Progress

Misc bits
Ruby programming

Buy my Assembly programming book
on Amazon in Print or Kindle!

Buy my Assembly programming book

Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!

Buy my Assembly programming book
on Amazon in Print or Kindle!

Buy my Assembly programming book

Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!

Buy my Assembly programming book
on Amazon in Print or Kindle!

Buy my Assembly programming book

Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!