The 6800 was too expensive for the
mainstream, and it had many of its features cut, and was released
as the 6502... it's second accumulator gone, it's command
set cut back - and everyone forgot about the 6800.... But the 6800 came back - as the 6809... with new previously unheard-of powers!... armed with twin stack pointers , 16 bit Stack,X and Y registers- 16 bit capabilities and advanced addressing modes and even a MULTiply command (unheard of in most 8 bits)... the 6809 is the 'missing link' between the 6502 and the 68000! Powering the Dragon 32, the FM-7 machines - and the unique Vectrex... Lets see what the 6809 can do! |
![]() |
Lesson 1 - Getting started with 6309 Assembly [DGN] |
Lesson 2 - Shifts, Compares and logical ops [DGN] |
Lesson 3 - More new commands! [DGN] |
Lesson H4 - Hello World on the Dragon / Tandy CoCo [DGN] |
Lesson H5 - Hello World on the Tandy CoCo Disk BIN file [DGN] |
Lesson M1 - Random Numbers and Ranges |
Lesson M2 - Binary Coded Decimal |
Lesson SuckShoot1 - Suck Shoot on the Vectrex [VTX] |
Lesson SuckShoot2 - Suck Shoot on the Dragon [DGN] |
Lesson SuckShoot3 - Suck Shoot on the FM7 [FM7] |
![]() |
If
you
want to learn 6809 get the Cheatsheet
collection! it has all the 6809 commands, It will
give you a quick reference when you're stuck or confused, which
will probably happen a lot in the early days! it also covers the
6309. |
![]() |
![]() |
We'll be using
Macroassembler AS for our assembly in these tutorials... VASM is
an assembler which supports rarer CPU's like 6809 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 |
![]() |
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!!! 6809 code is small, fast, and super efficient - with ASM you can do things in 1k that will amaze you! |
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 |
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 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! |
![]() |
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! |
|
Flags: EFHINZVC
|
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 |
![]() |
Address | Vector (Address) | Registers Auto-pushed onto stack |
$FFF2 | SWi 3
Vector |
D,X,Y,U,DP,CC |
$FFF4 | SWI 2
Vector |
D,X,Y,U,DP,CC |
$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 |
$FFFC | NMI Vector | D,X,Y,U,DP,CC |
$FFFE | RESET Vector | NA |
Group | Addressing Mode | Details | Example |
Inherent Addressing | Commands that don't take a parameter | ABX | |
Register Addressing | Commands that only use registers | TFR A,DP | |
Imm | Immediate Addressing | Direct Address of command | ADDA #$10 ADDD #$1000 |
DirectPg | Direct Page addressing | Read from DP (zero page) | ADDA $10 |
Ext | Extended Direct addressing | Read from an address | ADDA $1234 |
Index | Indexed Addressing | Uses a 2nd setting byte - allows for Autoinc | ,R offset,R label,pcr ,R+ ,-R [] |
Index | Extended Indirect Addressing | Read from the address specified... then get the value from that address | ADDA [$1234] |
Index | Indexed Addressing: Zero Offset | Just use the address in the register | LDA ,Y LDA 0,Y LDA Y |
Index | Indexed Addressing: Constant Offset from base register | 5 / 8 / 16 bit offset from X,Y,U,S ... Can be negative or positive | LDA 1000,Y |
Index | Indexed Addressing: Constant Offset From PC | 8 / 16 bit offset from PC | LDA $10,PC |
Index | Program counter relative | PCR is like PC, but is calculated by the assembler | ADDA label,PCR |
Index | Indirect with constant offset from base register | Load from the address in the register + offset | LDA [1,X] |
Index | Accumulator offset from Base register | Add accumulator (A/B/D) to a X,Y,U,S (not PC) | LDA B,Y |
Index | Indirect Accumulator offset from Base register | Load from the address made up of a X,Y,U,S Plus the accumulator | LDA [B,Y] |
Index | AutoIncrement | Add 1 or 2 to the register (no offset) | ADDA X+ ADDA ,X++ |
Index | AutoDecrement | Subtract 1 or 2 from the register (no offset) | ADDA -X ADDA ,--X |
Index | Indirect AutoIncrement | Load from the address in Register, then add 2 (can't add 1) | ADDA [,X++] |
Index | Indirect AutoDecrement | Subtract 2 then Load from the address in Register (can't subtract 1) | ADDA [,--X] |
Program relative | Offset to PC | BRA label |
Category | Version |
Direct Eg |
Indirect Eg |
Constant Offset from base register | None 5 bit 8 bit 16 bit |
,X 1,X 32,X 16384,X |
[,X] {n/a - 8 bit only} [32,X] [16384,X] |
Accumulator offset from Base register | A B D |
A,X B,X D,X |
[A,X] [B,X] [D,X] |
AutoIncrement / AutoDecrement | + ++ - -- |
X+ X++ X- X-- |
{n/a} [X++] {n/a} [X--] |
Constant Offset From PC | 8 bit 16 bit |
32,PC 16384,PC |
[32,PC] [16384,PC] |
Extended Indirect | 16 bit | {n/a} | [$8000] |
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 |
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 | |
DeX |
LEAX -1,X |
|
ABY (Add B to Y) |
LEAY B,Y |
|
SED | OrCC #%00010000 | |
SEI | AndCC #%11101111 | |
TAY | TFR A,B CLRA TFR D,Y |
|
LDA #>$1234 | LDA #$1234&255 | |
LDA #<$1234 | LDA #$1234>>8 |
![]() |
This
example will work fine on the Dragon 32 and the FM7 It will not work on the Vectrex!... that's because the Vectrex is a vector based system, and the text routines will not work on that system. |
![]() |
You'll see lots of JSR command - this is
like a GOSUB in basic, it jumps to a subroutine... RTS is the
equivalent of RETURN... JMP is like GOTO... don't worry too much though... we'll see these again later. |
Specifying
addresses in the direct page uses One byte, compared to the normal
Two, so memory in this area saves program code and is faster. The Direct page should be used as a 'Temporary store' for values you don't have enough register for. |
![]() |
![]() |
You'll notice that
many of the commands on the 6809 are the same as the 6502, but
many are different on the 6809 Both have their 'roots' in the 6800, and the 6809 has some compatibility with the old cpu, but code would need recompiling for the 6809... Next time we'll take a look at addressing modes - and we'll learn about all the impressive options the 6809 offers. |
Register addressing is where we specify a register by name as a source or destination | ![]() |
The source and destination are registers - we copied A to B! | ![]() |
We've seen Immediate addressing before, this is where a fixed value is specified with the command with a # symbol, and that value is used as the parameter | ![]() |
Here is the result | ![]() |
![]() |
Don't forget!
Unlike the 6502 the 6809 is BIG ENDIAN... the value $1234 will
be stored in memory as $12 $34 It sounds logical if you're used to the 68000 - but it will be a shock to the 6502 or z80 users! |
![]() |
Actually, the offset doesn't have to be a
fixed number - we can use the Accumulator as an offset! This has a different name though... "Accumulator offset from Base register" |
We can specify a label as a parameter by offset using PCR
as the parameter, an the label as the offset, the assembler will calculate the offset for us. |
![]() |
The data has been loaded in | ![]() |
Lesson
3 - Carry, Branch, Test We need to learn about conditions and branching... which brings up the topic of Flags! Lets learn about it all! |
![]() |
![]() |
![]() |
When we do a mathematical operation like ADD or SUB, there is
the possibility that the mathematical operation will cause the
value in the register to go over 255 or under 0, causing a 'Carry'
or 'Borrow' If we want, we can use an extra register as a second byte (in a 16 bit pair - or more) An ADD or SUB command will set the carry (also used as borrow)... we then use ADC for Add with Carry, or SBC for Subtract with carry - which will Add or subtract a value PLUS the Carry flag (if set) |
![]() |
Here are the results... when the Carry flag was set, the High byte (A) is affected by the ADC or SBC. | ![]() |
![]() |
We've looked at
ADD and SUB, but many other commands affect and use the carry
flag, Rotate commands will shift bits around the register, and some will use the carry too. |
To properly learn about how commands affect these
flags, and the branches, you really need to download the source,
and change the commands. If you REM (;) out the last ADDA, you'll leave the carry flag set, and the BCC branch will happen. What? you thought you didn't need to try things yourself? Good luck with that! |
![]() |
![]() |
The CMP
commands are actually a 'simulated subtraction' - in the sense
that they set the flags the same as a SUB would, but they leave
the register unchanged. That's why Z is set if the two compared values are the same. |
Finally we have to exceptions that don't look at the flags BRA will BRanch Always BRN will BRanch Never BRN is useless really, it's just a 'quirk' of the instruction set. |
![]() |
Unsurprisingly BRA occurred! | ![]() |
![]() |
BRN is pretty useless, but it could be
handy for self modifying code! Self modifying code is code that re-writes itself, for example, you may wish to modify a jump to turn it off.. changing BRA to BRN will do this! |
'Stacks' in assembly are like an
'In tray' for temporary storage... Imagine we have an In-Tray... we can put items in it, but only ever take the top item off... we can store lots of paper - but have to take it off in the same order we put it on!... this is what a stack does! If we want to temporarily store a register - we can put it's value on the top of the stack... but we have to take them off in the same order... The stack will appear in memory, and the stack pointer goes DOWN with each push on the stack... so if it starts at $01FF and we push 1 byte, it will point to $01FE |
![]() ![]() |
We can push and pull any of the registers onto the stack... 8 Bit accumulators A or B, 16 bit registers X, Y or D, the Stack pointers themselves S, U the program counter PC, or the 8 bit flags (CC) | ![]() |
![]() |
While JSR pushes
the address of the next command onto the stack, RTS effectively
pops an item off the main stack (S) into the Program counter
(PC) JSR always uses the main stack (S) not the user stack (U). |
No matter how many or few registers we push
or pull the command always ends up being two bytes. Therefore, if we need to end our sub with a PULS we can save one byte by adding the PC to the list... PC is always the last register popped off the stack if it's in the PULS list. |
![]() |
Command | Accumulator | Parameter | Result |
AND | 1 0 1 0 |
1 1 0 0 |
1 0 0 0 |
ORA | 1 0 1 0 |
1 1 0 0 |
1 1 1 0 |
EOR | 1 0 1 0 |
1 1 0 0 |
0 1 1 0 |
Command | lda #%10101010 eor #%11110000 |
lda #%10101010 and #%11110000 |
lda #%10101010 ora #%11110000 |
Result | #%01011010 | #%10100000 | #%11111010 |
Meaning | Invert the bits where the mask bits are 1 |
return 1 where both bits are1 | Return 1 when either bit is 1 |
Sample | EOR %11110000 Invert Bits that are 1 |
AND %11110000 Keep Bits that are 1 |
ORA %11110000 Set Bits that are 1 |
![]() |
![]() |
![]() |
![]() |
![]() |
You need to
download the source code and unrem the alternate shifts to see
them in operation! What do you mean, you can't be bothered! Grr... I don't know, the youth of today are sooo lazy! |
There may be times when you
want to sign extend an 8 bit register to 16 bits - effectively
filling the top byte with the top bit of the low byte. We can do this with the dubiously named 'SEX' command.... this sign extends B into A... so the D register now contains a 16 bit version of the signed number In this example we load some junk into A - then we load a test number into B - and sign extend it. |
![]() |
When the top bit was zero... A was
set to %00000000 ($00) When the top bit was one... A was set to %11111111 ($FF) |
![]() |
We have some commands to set flags based on a register without
changing it the BIT commands allow us to provide a bitmask - this is effectively the equivalent of an AND command - but does not actually change the register TST sets the flags according to a register (or memory address) and sets the flags accordingly - we can use it to check if a register contains zero |
![]() |
BIT will compare the selected bits, and
set the Z flag if the bits that were 1 in the parameter are 0 in
the tested register. TST will set the flags according to the register or memory address... in this case we set the Zero flag when A=0... and the Negative flag when A was <0 |
![]() |
Binary coded decimal is where we use a byte to store two decimal
digits (one per nibble).... Actually they are stored as 'hexadecimal' however the digits never go over 9... for example $09 + 1 = $10 and $0099 +1 = $0100 DAA will decimal adjust the A accumulator (it cannot work on B)... this should be done after addition, and will correct the accumulator, converting numbers like $0A to $10 |
![]() |
The Two nibbles act as a pair of decimal numbers (even though they are actually base 16) | ![]() |
The MUL command will multiply A * B and store the result in D | ![]() |
in this example we multiplied $69 by $10 ... The result? $0690 | ![]() |
![]() |
We've learned how
to Multiply... Wondering where the Divide command is?... Well,
um, there isn't one! You've got a MUL command - that's more than the Z80 or 6502 had... stop being so demanding! |
Cmd | Meaning | Inherent | Immediate | Direct | Exteded | Indx/Indir | Relative | H N Z V C |
ABX | Add B to X | $3A (3/1) | - - - - - | |||||
ADCA | Add with Carry to A | $89 (2/2) | $99 (4/2) | $B9 (5/3) | $A9 (4+/2+) | * * * * * | ||
ADCB | Add with Carry to B | $C9 (2/2) | $D9 (4/2) | $F9 (5/3) | $E9 (4+/2+) | * * * * * | ||
ADDA | Add to A | $8B (2/2) | $9B (4/2) | $BB (5/3) | $AB (4+/2+) | * * * * * | ||
ADDB | Add to B | $CB (2/2) | $DB (4/2) | $FB (5/3) | $EB (4+/2+) | * * * * * | ||
ADDD | add to AB (16 bit) | $C3 (4/3) | $D3 (6/2) | $F3 (7/3) | $E3 (6+/2+) | - * * * * | ||
ANDA | And with A | $84 (2/2) | $94 (4/2) | $B4 (5/3) | $A4 (4+/2+) | - * * 0 - | ||
ANDB | And with B | $C4 (2/2) | $D4 (4/2) | $F4 (5/3) | $E4 (4+/2+) | - * * 0 - | ||
ANDCC | And with ConditionCode | $1C (3/2) | - - - - 7 | |||||
ASL | Arithmatic Shift Left | $08 (6/2) | $78 (7/3) | $68 (6+/2+) | 8 * * * * | |||
ASLA | Arithmatic Shift Left A | $48 (2/1) | 8 * * * * | |||||
ASLB | Arithmatic Shift Left B | $58 (2/1) | 8 * * * * | |||||
ASR | Arithmatic Shift Right | $07 (6/2) | $77 (7/3) | $67 (6+/2+) | 8 * * - * | |||
ASRA | Arithmatic Shift Right A | $47 (2/1) | 8 * * - * | |||||
ASRB | Arithmatic Shift Right B | $46 (2/1) | 8 * * - * | |||||
BCC | Branch if Carry Clear C=0 | $24 (3/2) | - - - - - | |||||
BCS | Branch if Carry Set C=1 | $25 (3/2) | - - - - - | |||||
BEQ | Branch if Equal Z=1 | $27 (3/2) | - - - - - | |||||
BGE | Branch if Greater than or equal to zero | $2C (3/2) | - - - - - | |||||
BGT | Branch if Greater than Zero | $2E (3/2) | - - - - - | |||||
BHI | Branch if Higher Z+C=0 | $22 (3/2) | - - - - - | |||||
BHS | Branch if Higher or Same C=0 | $24 (3/2) | - - - - - | |||||
BITA | Bit Test A | $85 (2/2) | $95 (4/2) | $B5 (5/3) | $A5 (4+/2+) | 8 * * 0 * | ||
BITB | Bit Test B | $C5 (2/2) | $D5 (4/2) | $F5 (5/3) | $E5 (4+/2+) | 8 * * 0 * | ||
BLE | Branch if Less than or Equal to Zero | $2F (3/2) | - - - - - | |||||
BLO | Branch if Lower C=1 | $25 (3/2) | - - - - - | |||||
BLS | Branch if Lower or Same C+Z=1 | $23 (3/2) | - - - - - | |||||
BLT | Branch if Less Than Zero | $2D (3/2) | - - - - - | |||||
BMI | Branch if Minus N=1 | $2B (3/2) | - - - - - | |||||
BNE | Branch if Not Equal to Zero Z=0 | $26 (3/2) | - - - - - | |||||
BPL | Branch if Plus N=0 | $2A (3/2) | - - - - - | |||||
BRA | Branch Always | $20 (3/2) | - - - - - | |||||
BRN | Branch Never | $21 (3/2) | - - - - - | |||||
BSR | Branch to Subroutine | $8D (3/2) | - - - - - | |||||
BVC | Branch if Overflow Clear V=0 | $28 (3/2) | - - - - - | |||||
BVS | Branch if Overflow Set V=1 | $29 (3/2) | - - - - - | |||||
CLR | Clear | $0F (6/2) | $7F (7/3) | $6F (6+/2+) | - 0 1 0 0 | |||
CLRA | Clear A | $4F (2/1) | - 0 1 0 0 | |||||
CLRB | Clear B | $5F (2/1) | - 0 1 0 0 | |||||
CMPA | Compare with A | $81 (2/2) | $91 (4/2) | $B1 (5/3) | $A1 (4+/2+) | 8 * * * * | ||
CMPB | Compare with B | $C1 (2/2) | $D1 (4/2) | $F1 (5/3) | $E1 (4+/2+) | 8 * * * * | ||
CMPD | Compare with AB | $10 83 (5/4) | $10 93 (7/3) | $10 B3 (8/4) | $10 A3 (7+/3+) | - * * * * | ||
CMPS | Compare with S | $11 8C (5/4) | $11 9C (7/3) | $11 BC (8/4) | $11 AC (7+/3+) | - * * * * | ||
CMPU | Compare with U | $11 83 (5/4) | $11 93 (7/3) | $11 B3 (8/4) | $11 A3 (7+/3+) | - * * * * | ||
CMPX | Compare with X | $8C (4/3) | $9C (6/2) | $BC (7/3) | $AC (6+/2+) | - * * * * | ||
CMPY | Compare with Y | $10 8C (5/4) | $10 9C (7/3) | $10 BC (8/4) | $10 AC (7+/3+) | - * * * * | ||
COM | Complement | $03 (6/2) | $73 (7/3) | $63 (6/2) | - * * 0 1 | |||
COMA | Complement A | $43 (2/1) | - * * 0 1 | |||||
COMB | Complement B | $53 (2/1) | - * * 0 1 | |||||
CWAI | And with CC and Wait | $3C (20/2) | - - - - 7 | |||||
DAA | Decimal Adjust after Addition | $19 (2/1) | - * * 0 * | |||||
DEC | Decrement | $0A (6/2) | $7A (7/3) | $6A (6+/2+) | - * * * - | |||
DECA | Decrement A | $4A (2/1) | - * * * - | |||||
DECB | Decrement B | $5A (2/1) | - * * * - | |||||
EORA | Exclusive Or A (Xor) | $88 (2/2) | $98 (4/2) | $B8 (5/3) | $A8 (4+/2+) | - * * 0 - | ||
EORB | Exclusive Or B (Xor) | $C8 (2/2) | $D8 (4/2) | $F8 (5/3) | $E8 (4+/2+) | - * * 0 - | ||
EXG | Exchange Register Contents | $1E (8/2) | - - - - - | |||||
INC | Increment | $0C (6/2) | $7C (7/3) | $6C (6+/2+) | - * * * - | |||
INCA | Increment A | $4C (2/1) | - * * * - | |||||
INCB | Increment B | $5C (2/1) | - * * * - | |||||
JMP | Jump | $0E (3/2) | $7E (4/3) | $6E (3+/2+) | - - - - - | |||
JSR | Jump to Subroutine | $9D (7/2) | $BD (8/3) | $AD (7+/2+) | - - - - - | |||
LBCC | Long Branch if Carry Clear C=0 | $10 24 (5+/4) | - - - - - | |||||
LBCS | Long Branch if Carry Set C=1 | $10 25 (5+/4) | - - - - - | |||||
LBEQ | Long Branch if Equal Z=1 | $10 27 (5+/4) | - - - - - | |||||
LBGE | Long Branch if Greater than or equal to zero | $10 2C (5+/4) | - - - - - | |||||
LBGT | Long Branch if Greater than Zero | $10 2E (5+/4) | - - - - - | |||||
LBHI | Long Branch if Higher Z+C=0 | $10 22 (5+/4) | - - - - - | |||||
LBHS | Long Branch if Higher or Same C=0 | $10 24 (5+/4) | - - - - - | |||||
LBLE | Long Branch if Less than or Equal to Zero | $10 2F (5+/4) | - - - - - | |||||
LBLO | Long Branch if Lower C=1 | $10 25 (5+/4) | - - - - - | |||||
LBLS | Long Branch if Lower or Same C+Z=1 | $10 23 (5+/4) | - - - - - | |||||
LBLT | Long Branch if Less Than Zero | $10 2D (5+/4) | - - - - - | |||||
LBMI | Long Branch if Minus N=1 | $10 2B (5+/4) | - - - - - | |||||
LBNE | Long Branch if Not Equal to Zero Z=0 | $10 26 (5+/4) | - - - - - | |||||
LBPL | Long Branch if Plus N=0 | $10 2A (5+/4) | - - - - - | |||||
LBRA | Long Branch Always | $16 (5/3) | - - - - - | |||||
LBRN | Long Branch Never | $10 21 (5/4) | - - - - - | |||||
LBSR | Long Branch to Subroutine | $17 (9/3) | - - - - - | |||||
LBVC | Long Branch if Overflow Clear V=0 | $10 28 (5+/6) | - - - - - | |||||
LBVS | Long Branch if Overflow Set V=1 | $10 29 (5+/6) | - - - - - | |||||
LDA | Load A | $86 (2/2) | $96 (4/2) | $B6 (5/3) | $A6 (4+/2+) | - * * 0 - | ||
LDB | Load B | $C6 (2/2) | $D6 (4/2) | $F6 (5/3) | $E6 (4+/2+) | - * * 0 - | ||
LDD | Load AB | $CC (3/3) | $DC (5/2) | $FC (6/3) | $EC (5+/2+) | - * * 0 - | ||
LDS | Load S | $10 CE (4/4) | $10 DE (6/3) | $10 FE (7/4) | $10 EE (6+/3+) | - * * 0 - | ||
LDU | Load U | $CE (3/3) | $DE (5/2) | $FE (6/3) | $EE (5+/2+) | - * * 0 - | ||
LDX | Load X | $8E (3/3) | $9E (5/2) | $BE (6/3) | $AE (5+/2+) | - * * 0 - | ||
LDY | Load Y | $10 8E (4/4) | $10 9E (6/3) | $10 BE (7/4) | $10 AE (6+/3+) | - * * 0 - | ||
LEAS | Load Effective Address into S | $32 (4+/2+) | - - - - - | |||||
LEAU | Load Effective address into U | $33 (4+/2+) | - - - - - | |||||
LEAX | Load Effective Address into X | $30 (4+/2+) | - - * - - | |||||
LEAY | Load Effective Address into Y | $31 (4+/2+) | - - * - - | |||||
LSL | Logical Shift Left | $08 (6/2) | $78 (7/3) | $68 (6+/2+) | - * * * * | |||
LSLA | Logical Shift Left A | $48 (2/1) | - * * * * | |||||
LSLB | Logical Shift Left B | $58 (2/1) | - * * * * | |||||
LSR | Logical Shift Right | $04 (6/2) | $74 (7/3) | $64 (6+/2+) | - 0 * - * | |||
LSRA | Logical Shift Right A | $44 (2/1) | - 0 * - * | |||||
LSRB | Logical Shift Right B | $54 (2/1) | - 0 * - * | |||||
MUL | Multiply A*B � result in AB | $3D (11/1) | - - * - 9 | |||||
NEG | Negate | $00 (6/2) | $70 (7/3) | $60 (6+/2+) | 8 * * * * | |||
NEGA | Negate A | $40 (2/1) | 8 * * * * | |||||
NEGB | Negate B | $50 (2/1) | 8 * * * * | |||||
NOP | No Operation | $12 2/1 | - - - - - | |||||
ORA | Or A | $8A (2/2) | $9A (4/2) | $BA (5/3) | $AA (4+/2+) | - * * 0 - | ||
ORB | Or B | $CA (2/2) | $DA (4/2) | $FA (5/3) | $EA (4+/2+) | - * * 0 - | ||
ORCC | Or Condition Code | $1A (3/2) | - - - 7 - | |||||
PSHS | Push onto S stack (PC U Y X DP B A CC) | $34 (3/2) | - - - - - | |||||
PSHU | Push onto U stack (PC S Y X DP B A CC) | $36 (3/2) | - - - - - | |||||
PULS | Pull off S stack (PC U Y X DP B A CC) | $35 (3/2) | - - - - - | |||||
PULU | Pull off U stack (PC S Y X DP B A CC) | $37 (3/2) | - - - - - | |||||
ROL | Rotate Left through Carry | $09 (6/2) | $79 (7/3) | $69 (6+/2+) | - * * * * | |||
ROLA | Rotate Left through Carry A | $49 (2/1) | - * * * * | |||||
ROLB | Rotate Left through Carry B | $59 (2/1) | - * * * * | |||||
ROR | Rotate Right through Carry | $06 (6/2) | $76 (7/3) | $66 (6+/2+) | - * * - * | |||
RORA | Rotate Right through Carry A | $46 (2/1) | - * * - * | |||||
RORB | Rotate Right through Carry B | $56 (2/1) | - * * - * | |||||
RTI | Return from Interrupt | $3B (6/15) | - - - - 7 | |||||
RTS | Return From Subroutine | $39 (5/1) | - - - - - | |||||
SBCA | Subtract with Carry from A | $82 (2/2) | $92 (4/2) | $B2 (5/3) | $A2 (4+/2+) | 8 * * * * | ||
SBCB | Subtract with Carry from B | $C2 (2/2) | $D2 (4/2) | $F2 (5/3) | $E2 (4+/2+) | 8 * * * * | ||
SEX | Sign Extend B into AB | $1D (2/1) | - * * 0 - | |||||
STA | Store A | $97 (4/2) | $B7 (5/3) | $A7 (4+/2+) | - * * 0 - | |||
STB | Store B | $D7 (4/2) | $F7 (5/3) | $E7 (4+/2+) | - * * 0 - | |||
STD | Store AB | $DD (5/2) | $FD (6/3) | $ED (5+/2+) | - * * 0 - | |||
STS | Store S | $10 DF (6/3) | $10 FF (7/4) | $10 EF (6+/3+) | - * * 0 - | |||
STU | Store U | $DF (5/2) | $FF (6/3) | $EF (5+/2+) | - * * 0 - | |||
STX | Store X | $9F (5/2) | $BF (6/3) | $AF (5+/2+) | - * * 0 - | |||
STY | Store Y | $10 9F (6/3) | $10 BF (7/4) | $10 AF (6+/3+) | - * * 0 - | |||
SUBA | Subtract from A | $80 (2/2) | $90 (4/2) | $B0 (5/3) | $A0 (4+/2+) | 8 * * * * | ||
SUBB | Subtract from B | $C0 (2/2) | $D0 (4/2) | $F0 (5/3) | $E0 (4+/2+) | 8 * * * * | ||
SUBD | Subtract from AB | $83 (4/3) | $93 (6/2) | $B3 (7/3) | $A3 (6+/2+) | - * * * * | ||
SWI | Software Interrupt | $3F (19/1) | - - - - - | |||||
SWI2 | Software Interrupt 2 | $10 3F (20/2) | - - - - - | |||||
SWI3 | Software Interrupt 3 | $11 3F (20/2) | - - - - - | |||||
SYNC | Syncronise to Ext Event (wait for interrupt) | $13 (2/1) | - - - - - | |||||
TFR | Transfer Register to Register (X,Y,U,S,A,B,D,PC,CC) | $1F (7/2) | - - - - - | |||||
TST | Test (Set flags) | $0D (6/2) | $7D (6/3) | $6D (6+/2+) | - * * 0 - | |||
TSTA | Test A | $4D (2/1) | - * * 0 - | |||||
TSTB | Test B | $5D (2/1) | - * * 0 - |