Ok, I've ripped this html page on the web. I hope that anybody will annoy me for that, but I think it's a really great summary
of what you can learn of 6502 compatible chips.
I hope that mister Tabke will be ok !
By the way, anyone want to do an Oric with a 65816 CPU inside ? Could be cool, since this processor can emulate 6502 code.
At the end, you have a complete 6502/65C02/65816 opcode list, with compatiblity notes and timings.
Have fun reading this !
A 6502 Programmer's Introduction to the 65816
by Brett Tabke
After programming in 6502 language for over a decade, I was getting
a bit BORED. One can only code the same routines with the same opcodes
so many times before the nausea of repetition becomes overpowering. When
I heard the news that CMD was building a cartridge based on a 20 MHz 65816
I was overjoyed. For years I've heard those with 65816 bases systems brag
about its capabilities. To us old 6502 programmers, the opportunity to
program the fabled 65816 is a new lease on life.
The 65816 is an 8-/16-bit register selectable upgrade to the 6502
series processor. With 24 bit addressing of up to 16 Megabytes of RAM,
the powerful 65816 is a logical upgrade that leaves 6502 programmers
feeling right at home. It is amazing how fast one can adapt to the new
processor. It sounds funny to say it, but the only difficulty I have had
learning the 65816 is that there are so many options and choices to
complete the same task, that it is hard to decide which method is best.
To get started programming the 65816, I would recommend purchasing the
book, "Programming the 65816" from The Western Design Center,
manufacturer of the 65816. While it is a bit pricey, the sheer quality
and content of the 600 page book is worth the money. Rarely, if ever,
has there been a CPU manual as thorough and detailed as the Western Design
book. If you know 6502 assembly, then Programming the 65816 is probably
the only 65816 book you will ever need.
Getting a Feel for the Modes
The 65816 may be operated in Native mode or 6502 Emulation mode.
Emulation mode is a 100% 6502 compatible mode where the whole processor
looks and feels like a vintage 6502. Native mode offers 8- or 16-bit
user registers and full access to 24-bit addressing.
While in emulation mode, not only are all the 6502 opcodes present in
their virgin form, but the new 65816 instructions are also available for
usage. In fact, the first lesson to learn about programming the 65816 is
that emulation mode is much more powerful than a stock 6502. The only
true difference between emulation mode and our venerable C64's 6510
processor is that unimplemented opcodes will not produce the results
expected on the former. Since all 256 of the potential opcodes are now
implemented on the 65816, older C64 software that uses previously
unimplemented opcodes will produce erratic results.
To select between emulation and native modes, a new phantom hidden
emulation bit (E) was added to the status register. Shown in programming
models hanging on top of the Carry bit, the emulation bit is only
accessible by one instruction. The new instruction (XCE) exchanges the
status of the Carry bit and Emulation bit. To move to emulation mode,
set the carry and issue an XCE instruction. To move to native mode,
clear the carry and issue the XCE instruction.
My, How Your Index Registers Have Grown!
While in native mode there are two new directly accessible bits present
in the status register. The 65816 implements new hardware interrupt
vectors which include a new hardware BRK vector in ROM; therefore, the
old BRK bit of the status register is no longer needed. The BRK bit is
replaced with the X bit to select either 8- or 16-bit index registers.
The former empty bit 5 is now filled with the M bit to specify the
accumulator and memory access as 8- or 16-bit.
Two new instructions are used to clear or set bits within the status
register. The SEP instruction sets bits, and REP clears bits. SEP and
REP use a one byte immediate addressing mode operand to specify which
bits are to be set or cleared. For example, to set the X bit for 8 bit
user registers:
SEP #%00010000 | ; set bit 4 for 8-bit index
| | ; registers.
|
Or to clear bit 4:
REP #%00010000 | ; clear bit 4 for 16-bit index
| | ; registers.
|
When in 8 bit mode, the index registers perform their function in
standard 6502 form. When status bit X is set to 0, both the X and Y
index registers become 16 bits wide. With a 16-bit index register you can
now reach out to a full 64K with the various indexed addressing modes.
An absolute load to an index register in 16-bit mode will retrieve 2 bytes
of memory-the one at the effective address and the one at the effective
address plus one. Simple things like INX or DEY work on a full 16 bit,
which means you no longer have to specify a memory location for various
counters, and loops based on index counters can now be coded in a more
efficient manner.
The formerly empty status register bit 5 is now referred to as bit M.
M is used to specify an 8- or 16-bit wide acculmulator and memory
accesses. When in 8 bit mode, (M=1), the high order 8 bits are still
accessible by exchanging the low and high bytes with a XBA instruction-it
is like having two acculmulators! However; when set for a full 16-bit
wide accumulator, all math and accumulator oriented logical intructions
operate on all 16 bits! If you add up the clock cycles and bytes
required to perform a standard two byte addition, you can start to see
the true power of 16-bit registers.
More Register Improvements
Zero Page has now been renamed to Direct Page-corporate thinking, go
figure. A new processor register D was added to allow Direct Page to be
moved anywhere within the first 64K of memory. The direct page register
is 16 bits wide, so you can now specify the start of direct page at any
byte. Several old instructions now include direct page addressing as
well. To move direct page, just push the new value onto the stack (16
bits) and then PLD to pull it into the direct page register. You may
also transfer the value from the 16-bit accumulator to the direct page
register with the TCD instruction. Direct page may also be moved while
in emulation mode.
While in native mode, the stack pointer is a full 16 bits wide, which
means the stack is no longer limited to just 256 bytes. It can be moved
anywhere within the first 64K of memory (although while in emulation
mode, the stack is located at page one). There are several new
addressing modes that can use the stack pointer as a quasi-index register
to access memory. Numerous new push and pull instructions allow you to
manipulate the stack. A few of the more useful stack intructions useful
to programmers, are the new instructions to push & pull index registers
with PHX/PHY and PLX/PLY.
Two other new processors registers are the Program Bank Register (PBR)
and the Data Bank Register (DBR). The Program Bank Register can be
thought of as extending the program counter out to 24 bits. Although you
can JSR and JMP to routines located in other RAM banks, individual
routines on the 65816 still must run within a single bank of 64K-there's
no automatic rollover from one bank of RAM to the next when executing
successive instructions. In this sense, it may help to think of the
65816 processor as a marriage of Commodore's C128 Memory Management Unit
(MMU) and an 'enhanced' 6502-a very similar concept.
The Data Bank Register is used to reach out to any address within the
16 megabyte address space of the 65816. When any of the addressing modes
that specify a 16-bit address are used, the Data Bank byte is appended to
the instruction address. This allows access to all 16 megabytes without
having to resort to 24-bit addressing instruction, and helps enable code
that can operate from any bank.
New Addressing Modes
There are new addressing modes on the 65816. Several new instructions
are designed to help relocatable code that can execute at any address.
The use of relocatable code on the 6502 was extremely limited. With 16
megabytes of address space, writing relocatable code increases the
overall utility of the program. To write relocatable code, several new
instructions use Program Counter Relative Long addressing. This allows
relative branching within a 64K bank of RAM. There's also Stack Relative
addressing, and a push instruction to place the program counter onto the
stack, so that a code fragment can pull it back off and can instantly
know its execution address.
Another new feature are two Block Move instructions, one for forward
MVP and one for backward MVN. Simply load the 16-bit X register with the
starting address, the Y index register with the ending address, the
accumulator with the number of bytes to move, and issue the MVP or MVN
instructions. MVN is for move negative, and MVP is for move positive, so
that your moves don't overwrite themselves. Block Moves use two operand
bytes: one for the source bank of 64K and one for the destination bank.
Memory is moved at the rate of seven clock cycles per byte.
Several new addressing modes are used to access the full address
space. A 65816 assembler would decode "long" addressing given this input:
LDA $0445F2 | ; load byte from $45F2 of RAM
| | ; bank 4
|
LDA $03412F,x | ; load byte from $412F of bank 3
| | ; plus x.
|
Quite a few instructions have been given new addressing modes. How many
times have you wanted to do this:
LDA ($12) | ; load indirect without an
| | ; offset.
|
Or how about a table of routine addresses:
JSR ($1234,x) | ; jump to a subroutine via
| | ; indexed indirect addressing!
|
Other fun new instructions:
TXY,TYX | Transfer directly between index registers
| BRA | Branch always regardless of status bits
| TSB | Test and set any bit of a byte
| TRB | Test and reset (clear) any bit of a byte
| INC A/DEC A | Increment or decrement the accumulator directly
| STZ | Store a zero to any byte
|
Summing Up
As you can see, the 65816 opens up a whole new world of programming-it
feels like a new lease on life. Of course, it's going to take some time
to learn the new processor. But while the 20 MHz speed is a nice perk, I
believe that the real power of CMD's new peripheral is indeed the engine
under its hood: the 65816-a super CPU!
Native Mode Options
While in Native Mode, the m flag controls the size of
Accumulator A and most Memory Operations, while the x flag controls the
size of the X and Y Index Registers. This provides 4 different
configuration possibilities, as charted below. The REP and SEP
instructions are used in combination to swith configurations.
m | x | A/M | X/Y | Instructions
|
---|
0 | 0 | 15-bit | 16-bit | REP #$30
|
---|
0 | 1 | 16-bit | 8-bit | REP #$20
|
---|
| | | | SEP
#$10
|
---|
1 | 0 | 8-bit | 16-bit | REP #$10
|
---|
| | | | SEP
#$20 |
---|
1 | 1 | 8-bit | 8-bit | SEP #$30 |
---|
It is important to note that the m flag will control the size of all
operations dealing with memory except in operations involving the X and Y
Index Registers (CPX, CPY, LDX, LDY, STX and STY) when the x flag
controls the size.
Emulation Notes
While in Emulation Mode, Accumulator A is forced
to 8-bit mode. You can, however, access the
upper 8 bits with instructions that specify
Accumulator B, and all 16 bits at once
with instructions that specify Accumulator C. The X
and Y Index Registers are also forced to 8-bit
mode, with no means available to access the
upper 8 bits. To further assist in compatibility, the
Stack is forced to Page 1 of Bank 0. The Direct
page Register (D) is fully functional in this mode,
allowing direct page to be placed anywhere in
Bank 0. Likewise, the Program Bank Register
(PBR) and Data Bank Register (DBR) are also
fully functional. While it would seem that these
latter items would allow programs to operate from
any bank in Emulation mode, there are some
caveats; interrups will force the program bank to
zero without saving the PBR first, and RTI won't
attempt to restore the bank. Therefore, Native
mode would be recommended to execute
programs in other banks.
Guide to 6502/65C02/65816
Instructions | a |
| b |
| c |
| d |
| e |
| i |
| j |
| l |
| m |
| n |
| o |
| p |
| r |
| s |
| t |
| w |
| x |
Assembler Example | HEX | Addressing
Mode | 02 | C02 | 816 | Bytes | Cycles
|
---|
ADC Add With Carry [Flags affected:
n,v,z,c]
| ADC (dp,X) | 61 | DP Indexed
Indirect,X | x | x | x | 2 | 61,2,4
| ADC sr,S | 63 | Stack Relative
| | | x | 2 | 41,4
| ADC dp | 65 | Direct Page
| x | x | x | 2 | 31,2,4
| ADC [dp] | 67 | DP Indirect Long | | | x | 2 | 61,2,4
| ADC #const | 69 | Immediate | x | x | x | 217 | 21,4
| ADC addr | 6D | Absolute | x | x | x | 3 | 41,4
| ADC long | 6F | Absolute Long | | | x | 4 | 51,4
| ADC ( dp),Y | 71 | DP Indirect Indexed,
Y | x | x | x | 2 | 51,2,3,4
| ADC (dp) | 72 | DP Indirect | | x | x | 2 | 51,2,4
| ADC (sr,S),Y | 73 | SR Indirect
Indexed,Y | | | x | 2 | 71,4
| ADC dp,X | 75 | DP Indexed,X | x | x | x | 2 | 41,2,4
| ADC [dp],Y | 77 | DP Indirect Long
Indexed, Y | | | x | 2 | 61,2,4
| ADC addr,Y | 79 | Absolute Indexed,Y | x | x | x | 3 | 41,3,4
| ADC addr,X | 7D | Absolute Indexed,X | x | x | x | 3 | 41,3,4
| ADC long,X | 7F | Absolute Long
Indexed,X | | | x | 4 | 51,4
| AND AND Accumulator With Memory [Flags
affected: n,z]
| AND (dp,X) | 21 | DP Indexed
Indirect,X | x | x | x | 2 | 61,2
| AND sr,S | 23 | Stack Relative
| | | x | 2 | 41
| AND dp | 25 | Direct Page
| x | x | x | 2 | 31,2
| AND [dp] | 27 | DP Indirect Long | | | x | 2 | 61,2
| AND #const | 29 | Immediate | x | x | x | 217 | 21
| AND addr | 2D | Absolute | x | x | x | 3 | 41
| AND long | 2F | Absolute Long | | | x | 4 | 51
| AND (dp),Y | 31 | DP Indirect Indexed,
Y | x | x | x | 2 | 51,2,3
| AND (dp) | 32 | DP Indirect | | x | x | 2 | 51,2
| AND (sr,S),Y | 33 | SR Indirect
Indexed,Y | | | x | 2 | 71
| AND dp,X | 35 | DP Indexed,X | x | x | x | 2 | 41,2
| AND [dp],Y | 37 | DP Indirect Long
Indexed, Y | | | x | 2 | 61,2
| AND addr,Y | 39 | Absolute Indexed,Y | x | x | x | 3 | 41,3
| AND addr,X | 3D | Absolute Indexed,X | x | x | x | 3 | 41,3
| AND long,X | 3F | Absolute Long
Indexed,X | | | x | 4 | 51
| ASL Accumulator or Memory Shift Left
[Flags affected: n,z,c]
| ASL dp | 06 | Direct Page | x | x | x | 2 | 52,5
| ASL A | 0A | Accumulator | x | x | x | 1 | 2
| ASL addr | 0E | Absolute | x | x | x | 3 | 65
| ASL dp,X | 16 | DP Indexed,X | x | x | x | 2 | 62,5
| ASL addr,X | 1E | Absolute Indexed,X | x | x | x | 3 | 75,6
|
BCC Branch if Carry Clear
[Flags affected: none][Alias: BLT]
| BCC nearlabel | 90 | Program Counter
Relative | x | x | x | 2 | 27,8
| BCS Branch if Carry Set
[Flags affected: none][Alias: BGE]
| BCS nearlabel | B0 | Program Counter
Relative | x | x | x | 2 | 27,8
| BEQ Branch if Equal
[Flags affected: none]
| BEQ nearlabel | F0 | Program Counter
Relative | x | x | x | 2 | 27,8
| BIT Test Bits
[Flags affected: z (immediate mode) n,v,z (non-immediate modes)]
| BIT dp | 24 | Direct Page | x | x | x | 2 | 31,2
| BIT addr | 2C | Absolute | x | x | x | 3 | 41
| BIT dp,X | 34 | DP Indexed,X | | x | x | 2 | 41,2
| BIT addr,X | 3C | Absolute Indexed,X | | x | x | 3 | 41,3
| BIT #const | 89 | Immediate | | x | x | 217 | 21
| BMI Branch if Minus
[Flags affected: none]
| BMI nearlabel | 30 | Program Counter
Relative | x | x | x | 2 | 27,8
| BNE Branch if Not Equal
[Flags affected: none]
| BNE nearlabel | D0 | Program Counter
Relative | x | x | x | 2 | 27,8
| BPL Branch if Plus
[Flags affected: none]
| BPL nearlabel | 10 | Program Counter
Relative | x | x | x | 2 | 27,8
| BRA Branch Always
[Flags affected: none]
| BRA nearlabel | 80 | Program Counter
Relative | | x | x | 2 | 38
| BRK Break
[Flags affected: b,i (6502) b,d,i (65C02/65816 Emulation) d,i (65816 Native)]
| BRK | 00 | Stack/Interrupt
| x | x | x | 2
18
| 79
| BRL Branch Long Always
[Flags affected: none]
| BRL label | 82 | Program Counter
Relative Long | | | x | 3 | 4
| BVC Branch if Overflow Clear
[Flags affected: none]
| BVC nearlabel | 50 | Program Counter
Relative | x | x | x | 2 | 27,8
| BVS Branch if Overflow Set
[Flags affected: none]
| BVS nearlabel | 70 | Program Counter
Relative | x | x | x | 2 | 27,8
|
CLC Clear Carry
[Flags affected: c]
| CLC | 18 | Implied | x | x | x | 1 | 2
| CLD Clear Decimal Mode Flag
[Flags affected: d]
| CLD | D8 | Implied | x | x | x | 1 | 2
| CLI Clear Interrupt Disable Flag
[Flags affected: i]
| CLI | 58 | Implied | x | x | x | 1 | 2
| CLV Clear Overflow Flag
[Flags affected: v]
| CLV | B8 | Implied | x | x | x | 1 | 2
| CMP Compare Accumulator With Memory
[Flags affected: n,z,c]
| CMP (dp,X) | C1 | DP Indexed
Indirect,X | x | x | x | 2 | 61,2
| CMP sr,S | C3 | Stack Relative
| | | x | 2 | 41
| CMP dp | C5 | Direct Page
| x | x | x | 2 | 31,2
| CMP [dp] | C7 | DP Indirect Long | | | x | 2 | 61,2
| CMP #const | C9 | Immediate | x | x | x | 217 | 21
| CMP addr | CD | Absolute | x | x | x | 3 | 41
| CMP long | CF | Absolute Long | | | x | 4 | 51
| CMP (dp),Y | D1 | DP Indirect Indexed,
Y | x | x | x | 2 | 51,2,3
| CMP (dp) | D2 | DP Indirect | | x | x | 2 | 51,2
| CMP (sr,S),Y | D3 | SR Indirect
Indexed,Y | | | x | 2 | 71
| CMP dp,X | D5 | DP Indexed,X | x | x | x | 2 | 41,2
| CMP [dp],Y | D7 | DP Indirect Long
Indexed, Y | | | x | 2 | 61,2
| CMP addr,Y | D9 | Absolute Indexed,Y | x | x | x | 3 | 41,3
| CMP addr,X | DD | Absolute Indexed,X | x | x | x | 3 | 41,3
| CMP long,X | DF | Absolute Long
Indexed,X | | | x | 4 | 51
| COP Co-Processor Enable
[Flags affected: d,i]
| COP const | 02 | Stack/Interrupt
| | | x | 218
| 79
| CPX Compare Index Register X with Memory
[Flags affected: n,z,c]
| CPX #const | E0 | Immediate
| x | x | x | 219
| 210
| CPX dp | E4 | Direct Page
| x | x | x | 2
| 32,10
| CPX addr | EC | Absolute
| x | x | x | 3
| 410
| CPY Compare Index Register Y with Memory
[Flags affected: n,z,c]
| CPY #const | C0 | Immediate
| x | x | x | 219
| 210
| CPY dp | C4 | Direct Page
| x | x | x | 2
| 32,10
| CPY addr | CC | Absolute
| x | x | x | 3
| 410
|
DEC Decrement
[Flags affected: n,z]
| DEC A | 3A | Accumulator
| | x | x | 1
| 2
| DEC dp | C6 | Direct Page
| x | x | x | 2
| 52,5
| DEC addr | CE | Absolute
| x | x | x | 3
| 65
| DEC dp,X | D6 | DP Indexed,X
| x | x | x | 2
| 62,5
| DEC addr,X | DE | Absolute Indexed,X
| x | x | x | 3
| 75,6
| DEX Decrement Index Register X
[Flags affected: n,z]
| DEX | CA | Implied
| x | x | x | 1
| 2
| DEY Decrement Index Register Y
[Flags affected: n,z]
| DEY | 88 | Implied
| x | x | x | 1
| 2
|
EOR Exclusive-OR Accumulator with Memory
[Flags affected: n,z]
| EOR (dp,X) | 41 | DP Indexed
Indirect,X | x | x | x | 2 | 61,2
| EOR sr,S | 43 | Stack Relative
| | | x | 2 | 41
| EOR dp | 45 | Direct Page
| x | x | x | 2 | 31,2
| EOR [dp] | 47 | DP Indirect Long | | | x | 2 | 61,2
| EOR #const | 49 | Immediate | x | x | x | 217 | 21
| EOR addr | 4D | Absolute | x | x | x | 3 | 41
| EOR long | 4F | Absolute Long | | | x | 4 | 51
| EOR (dp),Y | 51 | DP Indirect Indexed,
Y | x | x | x | 2 | 51,2,3
| EOR (dp) | 52 | DP Indirect | | x | x | 2 | 51,2
| EOR (sr,S),Y | 53 | SR Indirect
Indexed,Y | | | x | 2 | 71
| EOR dp,X | 55 | DP Indexed,X | x | x | x | 2 | 41,2
| EOR [dp],Y | 57 | DP Indirect Long
Indexed, Y | | | x | 2 | 61,2
| EOR addr,Y | 59 | Absolute Indexed,Y | x | x | x | 3 | 41,3
| EOR addr,X | 5D | Absolute Indexed,X | x | x | x | 3 | 41,3
| EOR long,X | 5F | Absolute Long
Indexed,X | | | x | 4 | 51
|
INC Increment
[Flags affected: n,z]
| INC A | 1A | Accumulator | | x | x | 1 | 2
| INC dp | E6 | Direct Page | x | x | x | 2 | 52,5
| INC addr | EE | Absolute | x | x | x | 3 | 65
| INC dp,X | F6 | DP Indexed,X | x | x | x | 2 | 62,5
| INC addr,X | FE | Absolute Indexed,X | x | x | x | 3 | 75,6
| INX Increment Index Register X
[Flags affected: n,z]
| INX | E8 | Implied | x | x | x | 1 | 2
| INY Increment Index Register Y
[Flags affected: n,z]
| INY | C8 | Implied | x | x | x | 1 | 2
|
JMP Jump
[Flags affected: none][Alias: JML for all Long addressing modes]
| JMP addr | 4C | Absolute | x | x | x | 3 | 3
| JMP long | 5C | Absolute Long | | | x | 4 | 4
| JMP (addr) | 6C | Absolute Indirect | x | x | x | 3 | 511,12
| JMP (addr,X) | 7C | Absolute Indexed
Indirect | | x | x | 3 | 6
| JMP [addr] | DC | Absolute Indirect
Long | | | x | 3 | 6
| JSR Jump to Subroutine
[Flags affected: none][Alias: JSL for Absolute Long]
| JSR addr | 20 | Absolute | x | x | x | 3 | 6
| JSR long | 22 | Absolute Long | | | x | 4 | 8
| JSR (addr,X)) | FC | Absolute
Indexed Indirect | | | x | 3 | 8
|
LDA Load Accumulator from Memory
[Flags affected: n,z]
| LDA (dp,X) | A1 | DP Indexed
Indirect,X | x | x | x | 2 | 61,2
| LDA sr,S | A3 | Stack Relative
| | | x | 2 | 41
| LDA dp | A5 | Direct Page
| x | x | x | 2 | 31,2
| LDA [dp] | A7 | DP Indirect Long | | | x | 2 | 61,2
| LDA #const | A9 | Immediate | x | x | x | 217 | 21
| LDA addr | AD | Absolute | x | x | x | 3 | 41
| LDA long | AF | Absolute Long | | | x | 4 | 51
| LDA (dp),Y | B1 | DP Indirect Indexed,
Y | x | x | x | 2 | 51,2,3
| LDA (dp) | B2 | DP Indirect | | x | x | 2 | 51,2
| LDA (sr,S),Y | B3 | SR Indirect
Indexed,Y | | | x | 2 | 71
| LDA dp,X | B5 | DP Indexed,X | x | x | x | 2 | 41,2
| LDA [dp],Y | B7 | DP Indirect Long
Indexed, Y | | | x | 2 | 61,2
| LDA addr,Y | B9 | Absolute Indexed,Y | x | x | x | 3 | 41,3
| LDA addr,X | BD | Absolute Indexed,X | x | x | x | 3 | 41,3
| LDA long,X | BF | Absolute Long
Indexed,X | | | x | 4 | 51
| LDX Load Index Register X from Memory
[Flags affected: n,z]
| LDX #const | A2 | Immediate | x | x | x | 2
19
| 210
| LDX dp | A6 | Direct Page | x | x | x | 2 | 32,10
| LDX addr | AE | Absolute | x | x | x | 3 | 410
| LDX dp,Y | B6 | DP Indexed,Y | x | x | x | 2 | 42,10
| LDX addr,Y | BE | Absolute Indexed,Y | x | x | x | 3 | 43,10
| LDY Load Index Register Y from Memory
[Flags affected: n,z]
| LDY #const | A0 | Immediate | x | x | x | 2
19
| 210
| LDY dp | A4 | Direct Page | x | x | x | 2 | 32,10
| LDY addr | AC | Absolute | x | x | x | 3 | 410
| LDY dp,X | B4 | DP Indexed,X | x | x | x | 2 | 42,10
| LDY addr,X | BC | Absolute Indexed,X | x | x | x | 3 | 43,10
| LSR Logical Shift Memory or Accumulator
Right [Flags affected: n,z,c]
| LSR dp | 46 | Direct Page | x | x | x | 2
| 52,5
| LSR A | 4A | Accumulator | x | x | x | 1 | 2
| LSR addr | 4E | Absolute | x | x | x | 3 | 65
| LSR dp,X | 56 | DP Indexed,X | x | x | x | 2 | 62,5
| LSR addr,X | 5E | Absolute Indexed,X | x | x | x | 3 | 75,6
|
MVN Block Move Negative
[Flags affected: none][Registers: X,Y,C]
| MVN srcbk,destbk | 54 | Block Move | | | x | 3
| 13
| MVP Block Move Positive
[Flags affected: none][Registers: X,Y,C]
| MVN srcbk,destbk | 44 | Block Move | | | x | 3
| 13
|
NOP No Operation
[Flags affected: none]
| NOP | EA | Implied | x | x | x | 1
| 2
|
ORA OR Accumulator with Memory
[Flags affected: n,z]
| ORA (dp,X) | 01 | DP Indexed
Indirect,X | x | x | x | 2 | 61,2
| ORA sr,S | 03 | Stack Relative
| | | x | 2 | 41
| ORA dp | 05 | Direct Page
| x | x | x | 2 | 31,2
| ORA [dp] | 07 | DP Indirect Long | | | x | 2 | 61,2
| ORA #const | 09 | Immediate | x | x | x | 217 | 21
| ORA addr | 0D | Absolute | x | x | x | 3 | 41
| ORA long | 0F | Absolute Long | | | x | 4 | 51
| ORA (dp),Y | 11 | DP Indirect Indexed,
Y | x | x | x | 2 | 51,2,3
| ORA (dp) | 12 | DP Indirect | | x | x | 2 | 51,2
| ORA (sr,S),Y | 13 | SR Indirect
Indexed,Y | | | x | 2 | 71
| ORA dp,X | 15 | DP Indexed,X | x | x | x | 2 | 41,2
| ORA [dp],Y | 17 | DP Indirect Long
Indexed, Y | | | x | 2 | 61,2
| ORA addr,Y | 19 | Absolute Indexed,Y | x | x | x | 3 | 41,3
| ORA addr,X | 1D | Absolute Indexed,X | x | x | x | 3 | 41,3
| ORA long,X | 1F | Absolute Long
Indexed,X | | | x | 4 | 51
|
PEA Push Effective Absolute Address
[Flags affected: none]
| PEA addr | F4 | Stack (Absolute)
| | | x | 3 | 5
| PEI Push Effective Indirect Address
[Flags affected: none]
| PEI (dp) | D4 | Stack (DP Indirect)
| | | x | 2 | 62
| PER Push Effective PC Relative Indirect
Address [Flags affected: none]
| PER label | 62 | Stack (PC Relative Long)
| | | x | 3 | 6
| PHA Push Accumulator
[Flags affected: none]
| PHA | 48 | Stack (Push)
| x | x | x | 1 | 31
| PHB Push Data Bank Register
[Flags affected: none]
| PHB | 8B | Stack (Push)
| | | x | 1 | 3
| PHD Push Direct Page Register
[Flags affected: none]
| PHD | 0B | Stack (Push)
| | | x | 1 | 4
| PHK Push Program Bank Register
[Flags affected: none]
| PHK | 4B | Stack (Push)
| | | x | 1 | 3
| PHP Push Processor Status Register
[Flags affected: none]
| PHP | 08 | Stack (Push)
| x | x | x | 1 | 3
| PHX Push Index Register X
[Flags affected: none]
| PHX | DA | Stack (Push)
| | x | x | 1 | 310
| PHY Push Index Register Y
[Flags affected: none]
| PHY | 5A | Stack (Push)
| | x | x | 1 | 310
| PLA Pull Accumulator
[Flags affected: n,z]
| PLA | 68 | Stack (Pull)
| x | x | x | 1 | 41
| PLB Pull Data Bank Register
[Flags affected: n,z]
| PLB | AB | Stack (Pull)
| | | x | 1 | 4
| PLD Pull Direct Page Register
[Flags affected: n,z]
| PLD | 2B | Stack (Pull)
| | | x | 1 | 5
| PLP Pull Processor Status Register
[Flags affected: n,z]
| PLP | 28 | Stack (Pull)
| x | x | x | 1 | 4
| PLX Pull Index Register X
[Flags affected: n,z]
| PLX | FA | Stack (Pull)
| | x | x | 1 | 410
| PLY Pull Index Register Y
[Flags affected: n,z]
| PLY | 7A | Stack (Pull)
| | x | x | 1 | 410
|
REP Reset Processor Status Bits
[Flags affected: all except b per operand]
| REP #const | C2 | Immediate
| | | x | 2 | 3
| ROL Rotate Memory or Accumulator Left
[Flags affected:
n,z,c] | ROL dp | 26 | Direct Page | x | x | x | 2
| 52,5
| ROL A | 2A | Accumulator | x | x | x | 1 | 2
| ROL addr | 2E | Absolute | x | x | x | 3 | 65
| ROL dp,X | 36 | DP Indexed,X | x | x | x | 2 | 62,5
| ROL addr,X | 3E | Absolute Indexed,X | x | x | x | 3 | 75,6
| ROR Rotate Memory or Accumulator Right
[Flags affected:
n,z,c] | ROR dp | 66 | Direct Page | x | x | x | 2
| 52,5
| ROR A | 6A | Accumulator | x | x | x | 1 | 2
| ROR addr | 6E | Absolute | x | x | x | 3 | 65
| ROR dp,X | 76 | DP Indexed,X | x | x | x | 2 | 62,5
| ROR addr,X | 7E | Absolute Indexed,X | x | x | x | 3 | 75,6
| RTI Return from Interrupt
[Flags affected: all except b]
| RTI | 40 | Stack (RTI)
| x | x | x | 1 | 69
| RTL Return from Subroutine Long
[Flags affected: none]
| RTL | 6B | Stack (RTL)
| | | x | 1 | 6
| RTS Return from Subroutine
[Flags affected: none]
| RTS | 60 | Stack (RTS)
| x | x | x | 1 | 6
|
SBC Subtract with Borrow from Accumulator
[Flags affected: n,v,z,c]
| SBC (dp,X) | E1 | DP Indexed
Indirect,X | x | x | x | 2 | 61,2,4
| SBC sr,S | E3 | Stack Relative
| | | x | 2 | 41,4
| SBC dp | E5 | Direct Page
| x | x | x | 2 | 31,2,4
| SBC [dp] | E7 | DP Indirect Long | | | x | 2 | 61,2,4
| SBC #const | E9 | Immediate | x | x | x | 217 | 21,4
| SBC addr | ED | Absolute | x | x | x | 3 | 41,4
| SBC long | EF | Absolute Long | | | x | 4 | 51,4
| SBC (dp),Y | F1 | DP Indirect Indexed,
Y | x | x | x | 2 | 51,2,3,4
| SBC (dp) | F2 | DP Indirect | | x | x | 2 | 51,2,4
| SBC (sr,S),Y | F3 | SR Indirect
Indexed,Y | | | x | 2 | 71,4
| SBC dp,X | F5 | DP Indexed,X | x | x | x | 2 | 41,2,4
| SBC [dp],Y | F7 | DP Indirect Long
Indexed, Y | | | x | 2 | 61,2,4
| SBC addr,Y | F9 | Absolute Indexed,Y | x | x | x | 3 | 41,3,4
| SBC addr,X | FD | Absolute Indexed,X | x | x | x | 3 | 41,3,4
| SBC long,X | FF | Absolute Long
Indexed,X | | | x | 4 | 51,4
| SEC Set Carry Flag
[Flags affected: c]
| SEC | 38 | Implied
| x | x | x | 1 | 2
| SED Set Decimal Flag
[Flags affected: d]
| SED | F8 | Implied
| x | x | x | 1 | 2
| SEI Set Interrupt Disable Flag
[Flags affected: i]
| SEI | 78 | Implied
| x | x | x | 1 | 2
| SEP Set Processor Status Bits
[Flags affected: all except b per operand]
| SEP | E2 | Immediate
| | | x | 2 | 3
| STA Store Accumulator to Memory
[Flags affected: none]
| STA (dp,X) | 81 | DP Indexed
Indirect,X | x | x | x | 2 | 61,2
| STA sr,S | 83 | Stack Relative
| | | x | 2 | 41
| STA dp | 85 | Direct Page
| x | x | x | 2 | 31,2
| STA [dp] | 87 | DP Indirect Long | | | x | 2 | 61,2
| STA addr | 8D | Absolute | x | x | x | 3 | 41
| STA long | 8F | Absolute Long | | | x | 4 | 51
| STA (dp),Y | 91 | DP Indirect Indexed,
Y | x | x | x | 2 | 61,2
| STA (dp) | 92 | DP Indirect | | x | x | 2 | 51,2
| STA (sr,S),Y | 93 | SR Indirect
Indexed,Y | | | x | 2 | 71
| STA dpX | 95 | DP Indexed,X | x | x | x | 2 | 41,2
| STA [dp],Y | 97 | DP Indirect Long
Indexed, Y | | | x | 2 | 61,2
| STA addr,Y | 99 | Absolute Indexed,Y | x | x | x | 3 | 51
| STA addr,X | 9D | Absolute Indexed,X | x | x | x | 3 | 51
| STA long,X | 9F | Absolute Long
Indexed,X | | | x | 4 | 51
| STP Stop Processor
[Flags affected: none]
| STP | DB | Implied
| | | x | 1 | 314
| STX Store Index Register X to Memory
[Flags affected: none]
| STX dp | 86 | Direct Page
| x | x | x | 2 | 32,10
| STX addr | 8E | Absolute
| x | x | x | 3 | 410
| STX dp,Y | 96 | DP Indexed,Y
| x | x | x | 2 | 42,10
| STY Store Index Register Y to Memory
[Flags affected: none]
| STY dp | 84 | Direct Page
| x | x | x | 2 | 32,10
| STY addr | 8C | Absolute
| x | x | x | 3 | 410
| STY dp,X | 94 | DP Indexed,X
| x | x | x | 2 | 42,10
| STZ Store Zero to Memory
[Flags affected: none]
| STZ dp | 64 | Direct Page
| | x | x | 2 | 31,2
| STZ dp,X | 74 | DP Indexed,X
| | x | x | 2 | 41,2
| STZ addr | 9C | Absolute
| | x | x | 3 | 41
| STZ addr,X | 9E | Absolute Indexed,X
| | x | x | 3 | 51
|
TAX Transfer Accumulator to Index Register
X [Flags affected: n,z]
| TAX | AA | Implied
| x | x | x | 1 | 2
| TAY Transfer Accumulator to Index Register
Y [Flags affected: n,z]
| TAY | A8 | Implied
| x | x | x | 1 | 2
| TCD Transfer 16-bit Accumulator to Direct
Page Register [Flags affected: n,z]
| TCD | 5B | Implied
| | | x | 1 | 2
| TCS Transfer 16-bit Accumulator to Stack
Pointer [Flags affected: none]
| TCS | 1B | Implied
| | | x | 1 | 2
| TDC Transfer Direct Page Register to 16-bit
Accumulator [Flags affected: n,z]
| TDC | 7B | Implied
| | | x | 1 | 2
| TRB Test and Reset Memory Bits Against
Accumulator [Flags affected: z]
| TRB dp | 14 | Direct Page
| | x | x | 2 | 52,5
| TRB addr | 1C | Absolute
| | x | x | 3 | 63
| TSB Test and Set Memory Bits Against
Accumulator [Flags
affected: z] | TSB dp | 04 | Direct Page
| | x | x | 2 | 52,5
| TSB addr | 0C | Absolute
| | x | x | 3 | 65
| TSC Transfer Stack Pointer to 16-bit
Accumulator [Flags affected: n,z]
| TSC | 3B | Implied
| | | x | 1 | 2
| TSX Transfer Stack Pointer to Index
Register X [Flags affected: n,z]
| TSX | BA | Implied
| x | x | x | 1 | 2
| TXA Transfer Index Register X to
Accumulator [Flags affected: n,z]
| TXA | 8A | Implied
| x | x | x | 1 | 2
| TXS Transfer Index Register X to Stack
Pointer [Flags affected: none]
| TXS | 9A | Implied
| x | x | x | 1 | 2
| TXY Transfer Index Register X to Index
Register Y [Flags affected: n,z]
| TXY | 9B | Implied
| | | x | 1 | 2
| TYA Transfer Index Register Y to
Accumulator [Flags affected: n,z]
| TYA | 98 | Implied
| x | x | x | 1 | 2
| TYX Transfer Index Register Y to Index
Register X [Flags
affected: n,z] | TYX | BB | Implied
| | | x | 1 | 2
|
WAI Wait for Interrupt [Flags affected:
none] | WAI | CB | Implied
| | | x | 1 | 315
| WDM Reserved for Future Expansion
[Flags affected: none (subject to change)]
| WDM | 42 | n/a
| | | x | 2
16
| n/a16
|
XBA Exchange B and A 8-bit Accumulators
[Flags
affected: n,z] | XBA | EB | Implied
| | | x | 1 | 3
| XCE Exchange Carry and Emulation Flags
[Flags affected: m,b/x,c,e] | XCE | FB | Implied | | | x | 1 | 2
|
NOTES
1
Add 1 cycle if m=0 (16-bit memory/accumulator)
2
Add 1 cycle if low byte of Direct Page Register is non-zero
3
Add 1 cycle if adding index crosses a page boundary
4
Add 1 cycle if 65C02 and d=1 (65C02 in decimal mode)
5
Add 2 cycles if m=0 (16-bit memory/accumulator)
6
Subtract 1 cycle if 65C02 and no page boundary crossed
7
Add 1 cycle if branch is taken
8
Add 1 cycle if branch taken crosses page boundary on 6502, 65C02, or
65816's 6502 emulation mode (e=1)
9
Add 1 cycle for 65816 native mode (e=0)
10
Add 1 cycle if x=0 (16-bit index registers)
11
Add 1 cycle if 65C02
12
6502: Yields incorrect results if low byte of operand is $FF (i.e.,
operand is $xxFF)
13
7 cycles per byte moved
14
Uses 3 cycles to shut the processor down: additional cycles are required
by reset to restart it
15
Uses 3 cycles to shut the processor down: additional cycles are required
by interrupt to restart it
16
Byte and cycle counts subject to change in future processors which expand
WDM into 2-byte opcode portions of instructions of varying
lengths
17
Add 1 byte if m=0 (16-bit memory/accumulator)
18
Opcode is 1 byte, but program counter value pushed onto stack is
incremented by 2 allowing for optional signature byte
19
Add 1 byte if x=0 (16-bit index registers)
Copyright © 1996 Creative Micro Designs, Inc.
Reprinted
with permission from Commodore World magazine, Issue #16.
|