CPU unofficial opcodes: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(Better description of 文字广场+排雷, including the correct cartridge name.)
 
(35 intermediate revisions by 8 users not shown)
Line 1: Line 1:
"This is illegal, you know."
'''Unofficial opcodes''', sometimes called '''illegal opcodes''' or '''undocumented opcodes''', are [[6502 instructions|CPU instructions]] that were officially left unused by the original design. The 6502 family datasheet from MOS Technology does not specify or document their function, but they actually do perform various operations.
:Kravindish, Mayor of Sakado, ''Zelda: The Wand of Gamelon''


'''Unofficial opcodes''', sometimes misleadingly called '''[[wikipedia:Illegal opcode|illegal opcodes]]''' or '''undocumented opcodes''', are opcodes in a 6502 CPU that aren't documented in MOS Technology's official 6502 family datasheet. Some of these are useful; some are not predictable; some do nothing but burn cycles; some halt the CPU until reset. Most 6502 cores interpret them the same way, although there are slight differences.
Some of these instructions are useful; some are not predictable; some do nothing but burn cycles; some halt the CPU until reset.
Most NMOS 6502 cores interpret them the same way, although there are slight differences with the less stable instructions.
CMOS variants of the 6502 handle them completely differently, and later CPUs in the same family (e.g. 65C02, HuC6280, 65C816) were free to implement new instructions in the place of the unused ones.


The microcode of the 6502 is compressed.
An [[Accuracy|accurate]] NES emulator must implement all instructions, not just the official ones. A small number of games use them (see [[#Games using unofficial opcodes|below]]).
Instead of 256 lines telling how to process each separate opcode, it's encoded as combinational logic post-processing the output of a PLA that evaluates a function like this:
 
"If these bits are on, and these bits are off, do things on these six cycles." [http://www.pagetable.com/?p=39]
== Arrangement ==
Some instructions trip multiple PLA lines at once.
The microcode of the 6502 is compressed into a 130-entry decode ROM.
Instead of 256 entries telling how to process each separate opcode, it's encoded as combinational logic post-processing the output of a "sparse" ROM that acts in some ways like a programmable logic array (PLA).
Each entry in the ROM means "if these bits are on, and these bits are off, do things on these six cycles."<ref>Michael Steil. "[https://www.pagetable.com/?p=39 How MOS 6502 Illegal Opcodes really work]". ''Pagetable'', 2008-07-29. Accessed 2019-11-10.</ref>
 
Many instructions activate multiple lines of the decode ROM at once.
Often this is on purpose, such as one line for the addressing mode and one for the opcode part.
But many of the unofficial opcodes simultaneously trigger parts of the ROM that were intended for completely unrelated instructions.


Perhaps the pattern is easier to see by shuffling the 6502's opcode matrix.
Perhaps the pattern is easier to see by shuffling the 6502's opcode matrix.
Line 17: Line 24:
! ||+00||+01||+02||+03||+04||+05||+06||+07||+08||+09||+0A||+0B||+0C||+0D||+0E||+0F||+10||+11||+12||+13||+14||+15||+16||+17||+18||+19||+1A||+1B||+1C||+1D||+1E||+1F
! ||+00||+01||+02||+03||+04||+05||+06||+07||+08||+09||+0A||+0B||+0C||+0D||+0E||+0F||+10||+11||+12||+13||+14||+15||+16||+17||+18||+19||+1A||+1B||+1C||+1D||+1E||+1F
|- valign="top"
|- valign="top"
|00||style="background:#FCC"|BRK<br>||style="background:#CFC"|ORA<br>(d,x)||style="background:#CCF"|KIL<br>||style="background:#DDD"|SLO<br>(d,x)||style="background:#FCC"|NOP<br>d||style="background:#CFC"|ORA<br>d||style="background:#CCF"|ASL<br>d||style="background:#DDD"|SLO<br>d||style="background:#FCC"|PHP<br>||style="background:#CFC"|ORA<br>#i||style="background:#CCF"|ASL<br>||style="background:#DDD"|ANC<br>#i||style="background:#FCC"|NOP<br>a||style="background:#CFC"|ORA<br>a||style="background:#CCF"|ASL<br>a||style="background:#DDD"|SLO<br>a||style="background:#FCC"|BPL<br>*+d||style="background:#CFC"|ORA<br>(d),y||style="background:#CCF"|KIL<br>||style="background:#DDD"|SLO<br>(d),y||style="background:#FCC"|NOP<br>d,x||style="background:#CFC"|ORA<br>d,x||style="background:#CCF"|ASL<br>d,x||style="background:#DDD"|SLO<br>d,x||style="background:#FCC"|CLC<br>||style="background:#CFC"|ORA<br>a,y||style="background:#CCF"|NOP<br>||style="background:#DDD"|SLO<br>a,y||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|ORA<br>a,x||style="background:#CCF"|ASL<br>a,x||style="background:#DDD"|SLO<br>a,x
|00||style="background:#FCC"|BRK<br>||style="background:#CFC"|ORA<br>(d,x)||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''SLO'''<br>(d,x)||style="background:#FCC"|'''NOP'''<br>d||style="background:#CFC"|ORA<br>d||style="background:#CCF"|ASL<br>d||style="background:#DDD"|'''SLO'''<br>d||style="background:#FCC"|PHP<br>||style="background:#CFC"|ORA<br>#i||style="background:#CCF"|ASL<br>||style="background:#DDD"|'''ANC'''<br>#i||style="background:#FCC"|'''NOP'''<br>a||style="background:#CFC"|ORA<br>a||style="background:#CCF"|ASL<br>a||style="background:#DDD"|'''SLO'''<br>a||style="background:#FCC"|BPL<br>*+d||style="background:#CFC"|ORA<br>(d),y||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''SLO'''<br>(d),y||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#CFC"|ORA<br>d,x||style="background:#CCF"|ASL<br>d,x||style="background:#DDD"|'''SLO'''<br>d,x||style="background:#FCC"|CLC<br>||style="background:#CFC"|ORA<br>a,y||style="background:#CCF"|'''NOP'''<br>||style="background:#DDD"|'''SLO'''<br>a,y||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|ORA<br>a,x||style="background:#CCF"|ASL<br>a,x||style="background:#DDD"|'''SLO'''<br>a,x
|- valign="top"
|- valign="top"
|20||style="background:#FCC"|JSR<br>a||style="background:#CFC"|AND<br>(d,x)||style="background:#CCF"|KIL<br>||style="background:#DDD"|RLA<br>(d,x)||style="background:#FCC"|BIT<br>d||style="background:#CFC"|AND<br>d||style="background:#CCF"|ROL<br>d||style="background:#DDD"|RLA<br>d||style="background:#FCC"|PLP<br>||style="background:#CFC"|AND<br>#i||style="background:#CCF"|ROL<br>||style="background:#DDD"|ANC<br>#i||style="background:#FCC"|BIT<br>a||style="background:#CFC"|AND<br>a||style="background:#CCF"|ROL<br>a||style="background:#DDD"|RLA<br>a||style="background:#FCC"|BMI<br>*+d||style="background:#CFC"|AND<br>(d),y||style="background:#CCF"|KIL<br>||style="background:#DDD"|RLA<br>(d),y||style="background:#FCC"|NOP<br>d,x||style="background:#CFC"|AND<br>d,x||style="background:#CCF"|ROL<br>d,x||style="background:#DDD"|RLA<br>d,x||style="background:#FCC"|SEC<br>||style="background:#CFC"|AND<br>a,y||style="background:#CCF"|NOP<br>||style="background:#DDD"|RLA<br>a,y||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|AND<br>a,x||style="background:#CCF"|ROL<br>a,x||style="background:#DDD"|RLA<br>a,x
|20||style="background:#FCC"|JSR<br>a||style="background:#CFC"|AND<br>(d,x)||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''RLA'''<br>(d,x)||style="background:#FCC"|BIT<br>d||style="background:#CFC"|AND<br>d||style="background:#CCF"|ROL<br>d||style="background:#DDD"|'''RLA'''<br>d||style="background:#FCC"|PLP<br>||style="background:#CFC"|AND<br>#i||style="background:#CCF"|ROL<br>||style="background:#DDD"|'''ANC'''<br>#i||style="background:#FCC"|BIT<br>a||style="background:#CFC"|AND<br>a||style="background:#CCF"|ROL<br>a||style="background:#DDD"|'''RLA'''<br>a||style="background:#FCC"|BMI<br>*+d||style="background:#CFC"|AND<br>(d),y||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''RLA'''<br>(d),y||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#CFC"|AND<br>d,x||style="background:#CCF"|ROL<br>d,x||style="background:#DDD"|'''RLA'''<br>d,x||style="background:#FCC"|SEC<br>||style="background:#CFC"|AND<br>a,y||style="background:#CCF"|'''NOP'''<br>||style="background:#DDD"|'''RLA'''<br>a,y||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|AND<br>a,x||style="background:#CCF"|ROL<br>a,x||style="background:#DDD"|'''RLA'''<br>a,x
|- valign="top"
|- valign="top"
|40||style="background:#FCC"|RTI<br>||style="background:#CFC"|EOR<br>(d,x)||style="background:#CCF"|KIL<br>||style="background:#DDD"|SRE<br>(d,x)||style="background:#FCC"|NOP<br>d||style="background:#CFC"|EOR<br>d||style="background:#CCF"|LSR<br>d||style="background:#DDD"|SRE<br>d||style="background:#FCC"|PHA<br>||style="background:#CFC"|EOR<br>#i||style="background:#CCF"|LSR<br>||style="background:#DDD"|ALR<br>#i||style="background:#FCC"|JMP<br>a||style="background:#CFC"|EOR<br>a||style="background:#CCF"|LSR<br>a||style="background:#DDD"|SRE<br>a||style="background:#FCC"|BVC<br>*+d||style="background:#CFC"|EOR<br>(d),y||style="background:#CCF"|KIL<br>||style="background:#DDD"|SRE<br>(d),y||style="background:#FCC"|NOP<br>d,x||style="background:#CFC"|EOR<br>d,x||style="background:#CCF"|LSR<br>d,x||style="background:#DDD"|SRE<br>d,x||style="background:#FCC"|CLI<br>||style="background:#CFC"|EOR<br>a,y||style="background:#CCF"|NOP<br>||style="background:#DDD"|SRE<br>a,y||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|EOR<br>a,x||style="background:#CCF"|LSR<br>a,x||style="background:#DDD"|SRE<br>a,x
|40||style="background:#FCC"|RTI<br>||style="background:#CFC"|EOR<br>(d,x)||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''SRE'''<br>(d,x)||style="background:#FCC"|'''NOP'''<br>d||style="background:#CFC"|EOR<br>d||style="background:#CCF"|LSR<br>d||style="background:#DDD"|'''SRE'''<br>d||style="background:#FCC"|PHA<br>||style="background:#CFC"|EOR<br>#i||style="background:#CCF"|LSR<br>||style="background:#DDD"|'''ALR'''<br>#i||style="background:#FCC"|JMP<br>a||style="background:#CFC"|EOR<br>a||style="background:#CCF"|LSR<br>a||style="background:#DDD"|'''SRE'''<br>a||style="background:#FCC"|BVC<br>*+d||style="background:#CFC"|EOR<br>(d),y||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''SRE'''<br>(d),y||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#CFC"|EOR<br>d,x||style="background:#CCF"|LSR<br>d,x||style="background:#DDD"|'''SRE'''<br>d,x||style="background:#FCC"|CLI<br>||style="background:#CFC"|EOR<br>a,y||style="background:#CCF"|'''NOP'''<br>||style="background:#DDD"|'''SRE'''<br>a,y||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|EOR<br>a,x||style="background:#CCF"|LSR<br>a,x||style="background:#DDD"|'''SRE'''<br>a,x
|- valign="top"
|- valign="top"
|60||style="background:#FCC"|RTS<br>||style="background:#CFC"|ADC<br>(d,x)||style="background:#CCF"|KIL<br>||style="background:#DDD"|RRA<br>(d,x)||style="background:#FCC"|NOP<br>d||style="background:#CFC"|ADC<br>d||style="background:#CCF"|ROR<br>d||style="background:#DDD"|RRA<br>d||style="background:#FCC"|PLA<br>||style="background:#CFC"|ADC<br>#i||style="background:#CCF"|ROR<br>||style="background:#DDD"|ARR<br>#i||style="background:#FCC"|JMP<br>(a)||style="background:#CFC"|ADC<br>a||style="background:#CCF"|ROR<br>a||style="background:#DDD"|RRA<br>a||style="background:#FCC"|BVS<br>*+d||style="background:#CFC"|ADC<br>(d),y||style="background:#CCF"|KIL<br>||style="background:#DDD"|RRA<br>(d),y||style="background:#FCC"|NOP<br>d,x||style="background:#CFC"|ADC<br>d,x||style="background:#CCF"|ROR<br>d,x||style="background:#DDD"|RRA<br>d,x||style="background:#FCC"|SEI<br>||style="background:#CFC"|ADC<br>a,y||style="background:#CCF"|NOP<br>||style="background:#DDD"|RRA<br>a,y||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|ADC<br>a,x||style="background:#CCF"|ROR<br>a,x||style="background:#DDD"|RRA<br>a,x
|60||style="background:#FCC"|RTS<br>||style="background:#CFC"|ADC<br>(d,x)||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''RRA'''<br>(d,x)||style="background:#FCC"|'''NOP'''<br>d||style="background:#CFC"|ADC<br>d||style="background:#CCF"|ROR<br>d||style="background:#DDD"|'''RRA'''<br>d||style="background:#FCC"|PLA<br>||style="background:#CFC"|ADC<br>#i||style="background:#CCF"|ROR<br>||style="background:#DDD"|'''ARR'''<br>#i||style="background:#FCC"|JMP<br>(a)||style="background:#CFC"|ADC<br>a||style="background:#CCF"|ROR<br>a||style="background:#DDD"|'''RRA'''<br>a||style="background:#FCC"|BVS<br>*+d||style="background:#CFC"|ADC<br>(d),y||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''RRA'''<br>(d),y||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#CFC"|ADC<br>d,x||style="background:#CCF"|ROR<br>d,x||style="background:#DDD"|'''RRA'''<br>d,x||style="background:#FCC"|SEI<br>||style="background:#CFC"|ADC<br>a,y||style="background:#CCF"|'''NOP'''<br>||style="background:#DDD"|'''RRA'''<br>a,y||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|ADC<br>a,x||style="background:#CCF"|ROR<br>a,x||style="background:#DDD"|'''RRA'''<br>a,x
|- valign="top"
|- valign="top"
|80||style="background:#FCC"|NOP<br>#i||style="background:#CFC"|STA<br>(d,x)||style="background:#CCF"|NOP<br>#i||style="background:#DDD"|SAX<br>(d,x)||style="background:#FCC"|STY<br>d||style="background:#CFC"|STA<br>d||style="background:#CCF"|STX<br>d||style="background:#DDD"|SAX<br>d||style="background:#FCC"|DEY<br>||style="background:#CFC"|NOP<br>#i||style="background:#CCF"|TXA<br>||style="background:#DDD"|XAA<br>#i||style="background:#FCC"|STY<br>a||style="background:#CFC"|STA<br>a||style="background:#CCF"|STX<br>a||style="background:#DDD"|SAX<br>a||style="background:#FCC"|BCC<br>*+d||style="background:#CFC"|STA<br>(d),y||style="background:#CCF"|KIL<br>||style="background:#DDD"|AHX<br>(d),y||style="background:#FCC"|STY<br>d,x||style="background:#CFC"|STA<br>d,x||style="background:#CCF"|STX<br>d,y||style="background:#DDD"|SAX<br>d,y||style="background:#FCC"|TYA<br>||style="background:#CFC"|STA<br>a,y||style="background:#CCF"|TXS<br>||style="background:#DDD"|TAS<br>a,y||style="background:#FCC"|SHY<br>a,x||style="background:#CFC"|STA<br>a,x||style="background:#CCF"|SHX<br>a,y||style="background:#DDD"|AHX<br>a,y
|80||style="background:#FCC"|'''NOP'''<br>#i||style="background:#CFC"|STA<br>(d,x)||style="background:#CCF"|'''NOP'''<br>#i||style="background:#DDD"|'''SAX'''<br>(d,x)||style="background:#FCC"|STY<br>d||style="background:#CFC"|STA<br>d||style="background:#CCF"|STX<br>d||style="background:#DDD"|'''SAX'''<br>d||style="background:#FCC"|DEY<br>||style="background:#CFC"|'''NOP'''<br>#i||style="background:#CCF"|TXA<br>||style="background:#DDD"|'''XAA'''<br>#i||style="background:#FCC"|STY<br>a||style="background:#CFC"|STA<br>a||style="background:#CCF"|STX<br>a||style="background:#DDD"|'''SAX'''<br>a||style="background:#FCC"|BCC<br>*+d||style="background:#CFC"|STA<br>(d),y||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''AHX'''<br>(d),y||style="background:#FCC"|STY<br>d,x||style="background:#CFC"|STA<br>d,x||style="background:#CCF"|STX<br>d,y||style="background:#DDD"|'''SAX'''<br>d,y||style="background:#FCC"|TYA<br>||style="background:#CFC"|STA<br>a,y||style="background:#CCF"|TXS<br>||style="background:#DDD"|'''TAS'''<br>a,y||style="background:#FCC"|'''SHY'''<br>a,x||style="background:#CFC"|STA<br>a,x||style="background:#CCF"|'''SHX'''<br>a,y||style="background:#DDD"|'''AHX'''<br>a,y
|- valign="top"
|- valign="top"
|A0||style="background:#FCC"|LDY<br>#i||style="background:#CFC"|LDA<br>(d,x)||style="background:#CCF"|LDX<br>#i||style="background:#DDD"|LAX<br>(d,x)||style="background:#FCC"|LDY<br>d||style="background:#CFC"|LDA<br>d||style="background:#CCF"|LDX<br>d||style="background:#DDD"|LAX<br>d||style="background:#FCC"|TAY<br>||style="background:#CFC"|LDA<br>#i||style="background:#CCF"|TAX<br>||style="background:#DDD"|LAX<br>#i||style="background:#FCC"|LDY<br>a||style="background:#CFC"|LDA<br>a||style="background:#CCF"|LDX<br>a||style="background:#DDD"|LAX<br>a||style="background:#FCC"|BCS<br>*+d||style="background:#CFC"|LDA<br>(d),y||style="background:#CCF"|KIL<br>||style="background:#DDD"|LAX<br>(d),y||style="background:#FCC"|LDY<br>d,x||style="background:#CFC"|LDA<br>d,x||style="background:#CCF"|LDX<br>d,y||style="background:#DDD"|LAX<br>d,y||style="background:#FCC"|CLV<br>||style="background:#CFC"|LDA<br>a,y||style="background:#CCF"|TSX<br>||style="background:#DDD"|LAS<br>a,y||style="background:#FCC"|LDY<br>a,x||style="background:#CFC"|LDA<br>a,x||style="background:#CCF"|LDX<br>a,y||style="background:#DDD"|LAX<br>a,y
|A0||style="background:#FCC"|LDY<br>#i||style="background:#CFC"|LDA<br>(d,x)||style="background:#CCF"|LDX<br>#i||style="background:#DDD"|'''LAX'''<br>(d,x)||style="background:#FCC"|LDY<br>d||style="background:#CFC"|LDA<br>d||style="background:#CCF"|LDX<br>d||style="background:#DDD"|'''LAX'''<br>d||style="background:#FCC"|TAY<br>||style="background:#CFC"|LDA<br>#i||style="background:#CCF"|TAX<br>||style="background:#DDD"|'''LAX'''<br>#i||style="background:#FCC"|LDY<br>a||style="background:#CFC"|LDA<br>a||style="background:#CCF"|LDX<br>a||style="background:#DDD"|'''LAX'''<br>a||style="background:#FCC"|BCS<br>*+d||style="background:#CFC"|LDA<br>(d),y||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''LAX'''<br>(d),y||style="background:#FCC"|LDY<br>d,x||style="background:#CFC"|LDA<br>d,x||style="background:#CCF"|LDX<br>d,y||style="background:#DDD"|'''LAX'''<br>d,y||style="background:#FCC"|CLV<br>||style="background:#CFC"|LDA<br>a,y||style="background:#CCF"|TSX<br>||style="background:#DDD"|'''LAS'''<br>a,y||style="background:#FCC"|LDY<br>a,x||style="background:#CFC"|LDA<br>a,x||style="background:#CCF"|LDX<br>a,y||style="background:#DDD"|'''LAX'''<br>a,y
|- valign="top"
|- valign="top"
|C0||style="background:#FCC"|CPY<br>#i||style="background:#CFC"|CMP<br>(d,x)||style="background:#CCF"|NOP<br>#i||style="background:#DDD"|DCP<br>(d,x)||style="background:#FCC"|CPY<br>d||style="background:#CFC"|CMP<br>d||style="background:#CCF"|DEC<br>d||style="background:#DDD"|DCP<br>d||style="background:#FCC"|INY<br>||style="background:#CFC"|CMP<br>#i||style="background:#CCF"|DEX<br>||style="background:#DDD"|AXS<br>#i||style="background:#FCC"|CPY<br>a||style="background:#CFC"|CMP<br>a||style="background:#CCF"|DEC<br>a||style="background:#DDD"|DCP<br>a||style="background:#FCC"|BNE<br>*+d||style="background:#CFC"|CMP<br>(d),y||style="background:#CCF"|KIL<br>||style="background:#DDD"|DCP<br>(d),y||style="background:#FCC"|NOP<br>d,x||style="background:#CFC"|CMP<br>d,x||style="background:#CCF"|DEC<br>d,x||style="background:#DDD"|DCP<br>d,x||style="background:#FCC"|CLD<br>||style="background:#CFC"|CMP<br>a,y||style="background:#CCF"|NOP<br>||style="background:#DDD"|DCP<br>a,y||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|CMP<br>a,x||style="background:#CCF"|DEC<br>a,x||style="background:#DDD"|DCP<br>a,x
|C0||style="background:#FCC"|CPY<br>#i||style="background:#CFC"|CMP<br>(d,x)||style="background:#CCF"|'''NOP'''<br>#i||style="background:#DDD"|'''DCP'''<br>(d,x)||style="background:#FCC"|CPY<br>d||style="background:#CFC"|CMP<br>d||style="background:#CCF"|DEC<br>d||style="background:#DDD"|'''DCP'''<br>d||style="background:#FCC"|INY<br>||style="background:#CFC"|CMP<br>#i||style="background:#CCF"|DEX<br>||style="background:#DDD"|'''AXS'''<br>#i||style="background:#FCC"|CPY<br>a||style="background:#CFC"|CMP<br>a||style="background:#CCF"|DEC<br>a||style="background:#DDD"|'''DCP'''<br>a||style="background:#FCC"|BNE<br>*+d||style="background:#CFC"|CMP<br>(d),y||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''DCP'''<br>(d),y||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#CFC"|CMP<br>d,x||style="background:#CCF"|DEC<br>d,x||style="background:#DDD"|'''DCP'''<br>d,x||style="background:#FCC"|CLD<br>||style="background:#CFC"|CMP<br>a,y||style="background:#CCF"|'''NOP'''<br>||style="background:#DDD"|'''DCP'''<br>a,y||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|CMP<br>a,x||style="background:#CCF"|DEC<br>a,x||style="background:#DDD"|'''DCP'''<br>a,x
|- valign="top"
|- valign="top"
|E0||style="background:#FCC"|CPX<br>#i||style="background:#CFC"|SBC<br>(d,x)||style="background:#CCF"|NOP<br>#i||style="background:#DDD"|ISC<br>(d,x)||style="background:#FCC"|CPX<br>d||style="background:#CFC"|SBC<br>d||style="background:#CCF"|INC<br>d||style="background:#DDD"|ISC<br>d||style="background:#FCC"|INX<br>||style="background:#CFC"|SBC<br>#i||style="background:#CCF"|NOP<br>||style="background:#DDD"|SBC<br>#i||style="background:#FCC"|CPX<br>a||style="background:#CFC"|SBC<br>a||style="background:#CCF"|INC<br>a||style="background:#DDD"|ISC<br>a||style="background:#FCC"|BEQ<br>*+d||style="background:#CFC"|SBC<br>(d),y||style="background:#CCF"|KIL<br>||style="background:#DDD"|ISC<br>(d),y||style="background:#FCC"|NOP<br>d,x||style="background:#CFC"|SBC<br>d,x||style="background:#CCF"|INC<br>d,x||style="background:#DDD"|ISC<br>d,x||style="background:#FCC"|SED<br>||style="background:#CFC"|SBC<br>a,y||style="background:#CCF"|NOP<br>||style="background:#DDD"|ISC<br>a,y||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|SBC<br>a,x||style="background:#CCF"|INC<br>a,x||style="background:#DDD"|ISC<br>a,x
|E0||style="background:#FCC"|CPX<br>#i||style="background:#CFC"|SBC<br>(d,x)||style="background:#CCF"|'''NOP'''<br>#i||style="background:#DDD"|'''ISC'''<br>(d,x)||style="background:#FCC"|CPX<br>d||style="background:#CFC"|SBC<br>d||style="background:#CCF"|INC<br>d||style="background:#DDD"|'''ISC'''<br>d||style="background:#FCC"|INX<br>||style="background:#CFC"|SBC<br>#i||style="background:#CCF"|NOP<br>||style="background:#DDD"|'''SBC'''<br>#i||style="background:#FCC"|CPX<br>a||style="background:#CFC"|SBC<br>a||style="background:#CCF"|INC<br>a||style="background:#DDD"|'''ISC'''<br>a||style="background:#FCC"|BEQ<br>*+d||style="background:#CFC"|SBC<br>(d),y||style="background:#CCF"|'''STP'''<br>||style="background:#DDD"|'''ISC'''<br>(d),y||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#CFC"|SBC<br>d,x||style="background:#CCF"|INC<br>d,x||style="background:#DDD"|'''ISC'''<br>d,x||style="background:#FCC"|SED<br>||style="background:#CFC"|SBC<br>a,y||style="background:#CCF"|'''NOP'''<br>||style="background:#DDD"|'''ISC'''<br>a,y||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|SBC<br>a,x||style="background:#CCF"|INC<br>a,x||style="background:#DDD"|'''ISC'''<br>a,x
|}
|}


Key: a is a 16-bit absolute address, and d is an 8-bit zero page address.
Key: a is a 16-bit absolute address, and d is an 8-bit zero page address. Entries in bold represent unofficial opcodes.


But if we rearrange it so that columns with the same bits 1-0
But if we rearrange it so that columns with the same bits 1-0
Line 42: Line 49:
! ||+00||+04||+08||+0C||+10||+14||+18||+1C||+01||+05||+09||+0D||+11||+15||+19||+1D||+02||+06||+0A||+0E||+12||+16||+1A||+1E||+03||+07||+0B||+0F||+13||+17||+1B||+1F
! ||+00||+04||+08||+0C||+10||+14||+18||+1C||+01||+05||+09||+0D||+11||+15||+19||+1D||+02||+06||+0A||+0E||+12||+16||+1A||+1E||+03||+07||+0B||+0F||+13||+17||+1B||+1F
|- valign="top"
|- valign="top"
|00||style="background:#FCC"|BRK<br>||style="background:#FCC"|NOP<br>d||style="background:#FCC"|PHP<br>||style="background:#FCC"|NOP<br>a||style="background:#FCC"|BPL<br>*+d||style="background:#FCC"|NOP<br>d,x||style="background:#FCC"|CLC<br>||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|ORA<br>(d,x)||style="background:#CFC"|ORA<br>d||style="background:#CFC"|ORA<br>#i||style="background:#CFC"|ORA<br>a||style="background:#CFC"|ORA<br>(d),y||style="background:#CFC"|ORA<br>d,x||style="background:#CFC"|ORA<br>a,y||style="background:#CFC"|ORA<br>a,x||style="background:#CCF"|KIL<br>||style="background:#CCF"|ASL<br>d||style="background:#CCF"|ASL<br>||style="background:#CCF"|ASL<br>a||style="background:#CCF"|KIL<br>||style="background:#CCF"|ASL<br>d,x||style="background:#CCF"|NOP<br>||style="background:#CCF"|ASL<br>a,x||style="background:#DDD"|SLO<br>(d,x)||style="background:#DDD"|SLO<br>d||style="background:#DDD"|ANC<br>#i||style="background:#DDD"|SLO<br>a||style="background:#DDD"|SLO<br>(d),y||style="background:#DDD"|SLO<br>d,x||style="background:#DDD"|SLO<br>a,y||style="background:#DDD"|SLO<br>a,x
|00||style="background:#FCC"|BRK<br>||style="background:#FCC"|'''NOP'''<br>d||style="background:#FCC"|PHP<br>||style="background:#FCC"|'''NOP'''<br>a||style="background:#FCC"|BPL<br>*+d||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#FCC"|CLC<br>||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|ORA<br>(d,x)||style="background:#CFC"|ORA<br>d||style="background:#CFC"|ORA<br>#i||style="background:#CFC"|ORA<br>a||style="background:#CFC"|ORA<br>(d),y||style="background:#CFC"|ORA<br>d,x||style="background:#CFC"|ORA<br>a,y||style="background:#CFC"|ORA<br>a,x||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|ASL<br>d||style="background:#CCF"|ASL<br>||style="background:#CCF"|ASL<br>a||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|ASL<br>d,x||style="background:#CCF"|'''NOP'''<br>||style="background:#CCF"|ASL<br>a,x||style="background:#DDD"|'''SLO'''<br>(d,x)||style="background:#DDD"|'''SLO'''<br>d||style="background:#DDD"|'''ANC'''<br>#i||style="background:#DDD"|'''SLO'''<br>a||style="background:#DDD"|'''SLO'''<br>(d),y||style="background:#DDD"|'''SLO'''<br>d,x||style="background:#DDD"|'''SLO'''<br>a,y||style="background:#DDD"|'''SLO'''<br>a,x
|- valign="top"
|- valign="top"
|20||style="background:#FCC"|JSR<br>a||style="background:#FCC"|BIT<br>d||style="background:#FCC"|PLP<br>||style="background:#FCC"|BIT<br>a||style="background:#FCC"|BMI<br>*+d||style="background:#FCC"|NOP<br>d,x||style="background:#FCC"|SEC<br>||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|AND<br>(d,x)||style="background:#CFC"|AND<br>d||style="background:#CFC"|AND<br>#i||style="background:#CFC"|AND<br>a||style="background:#CFC"|AND<br>(d),y||style="background:#CFC"|AND<br>d,x||style="background:#CFC"|AND<br>a,y||style="background:#CFC"|AND<br>a,x||style="background:#CCF"|KIL<br>||style="background:#CCF"|ROL<br>d||style="background:#CCF"|ROL<br>||style="background:#CCF"|ROL<br>a||style="background:#CCF"|KIL<br>||style="background:#CCF"|ROL<br>d,x||style="background:#CCF"|NOP<br>||style="background:#CCF"|ROL<br>a,x||style="background:#DDD"|RLA<br>(d,x)||style="background:#DDD"|RLA<br>d||style="background:#DDD"|ANC<br>#i||style="background:#DDD"|RLA<br>a||style="background:#DDD"|RLA<br>(d),y||style="background:#DDD"|RLA<br>d,x||style="background:#DDD"|RLA<br>a,y||style="background:#DDD"|RLA<br>a,x
|20||style="background:#FCC"|JSR<br>a||style="background:#FCC"|BIT<br>d||style="background:#FCC"|PLP<br>||style="background:#FCC"|BIT<br>a||style="background:#FCC"|BMI<br>*+d||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#FCC"|SEC<br>||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|AND<br>(d,x)||style="background:#CFC"|AND<br>d||style="background:#CFC"|AND<br>#i||style="background:#CFC"|AND<br>a||style="background:#CFC"|AND<br>(d),y||style="background:#CFC"|AND<br>d,x||style="background:#CFC"|AND<br>a,y||style="background:#CFC"|AND<br>a,x||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|ROL<br>d||style="background:#CCF"|ROL<br>||style="background:#CCF"|ROL<br>a||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|ROL<br>d,x||style="background:#CCF"|'''NOP'''<br>||style="background:#CCF"|ROL<br>a,x||style="background:#DDD"|'''RLA'''<br>(d,x)||style="background:#DDD"|'''RLA'''<br>d||style="background:#DDD"|'''ANC'''<br>#i||style="background:#DDD"|'''RLA'''<br>a||style="background:#DDD"|'''RLA'''<br>(d),y||style="background:#DDD"|'''RLA'''<br>d,x||style="background:#DDD"|'''RLA'''<br>a,y||style="background:#DDD"|'''RLA'''<br>a,x
|- valign="top"
|- valign="top"
|40||style="background:#FCC"|RTI<br>||style="background:#FCC"|NOP<br>d||style="background:#FCC"|PHA<br>||style="background:#FCC"|JMP<br>a||style="background:#FCC"|BVC<br>*+d||style="background:#FCC"|NOP<br>d,x||style="background:#FCC"|CLI<br>||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|EOR<br>(d,x)||style="background:#CFC"|EOR<br>d||style="background:#CFC"|EOR<br>#i||style="background:#CFC"|EOR<br>a||style="background:#CFC"|EOR<br>(d),y||style="background:#CFC"|EOR<br>d,x||style="background:#CFC"|EOR<br>a,y||style="background:#CFC"|EOR<br>a,x||style="background:#CCF"|KIL<br>||style="background:#CCF"|LSR<br>d||style="background:#CCF"|LSR<br>||style="background:#CCF"|LSR<br>a||style="background:#CCF"|KIL<br>||style="background:#CCF"|LSR<br>d,x||style="background:#CCF"|NOP<br>||style="background:#CCF"|LSR<br>a,x||style="background:#DDD"|SRE<br>(d,x)||style="background:#DDD"|SRE<br>d||style="background:#DDD"|ALR<br>#i||style="background:#DDD"|SRE<br>a||style="background:#DDD"|SRE<br>(d),y||style="background:#DDD"|SRE<br>d,x||style="background:#DDD"|SRE<br>a,y||style="background:#DDD"|SRE<br>a,x
|40||style="background:#FCC"|RTI<br>||style="background:#FCC"|'''NOP'''<br>d||style="background:#FCC"|PHA<br>||style="background:#FCC"|JMP<br>a||style="background:#FCC"|BVC<br>*+d||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#FCC"|CLI<br>||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|EOR<br>(d,x)||style="background:#CFC"|EOR<br>d||style="background:#CFC"|EOR<br>#i||style="background:#CFC"|EOR<br>a||style="background:#CFC"|EOR<br>(d),y||style="background:#CFC"|EOR<br>d,x||style="background:#CFC"|EOR<br>a,y||style="background:#CFC"|EOR<br>a,x||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|LSR<br>d||style="background:#CCF"|LSR<br>||style="background:#CCF"|LSR<br>a||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|LSR<br>d,x||style="background:#CCF"|'''NOP'''<br>||style="background:#CCF"|LSR<br>a,x||style="background:#DDD"|'''SRE'''<br>(d,x)||style="background:#DDD"|'''SRE'''<br>d||style="background:#DDD"|'''ALR'''<br>#i||style="background:#DDD"|'''SRE'''<br>a||style="background:#DDD"|'''SRE'''<br>(d),y||style="background:#DDD"|'''SRE'''<br>d,x||style="background:#DDD"|'''SRE'''<br>a,y||style="background:#DDD"|'''SRE'''<br>a,x
|- valign="top"
|- valign="top"
|60||style="background:#FCC"|RTS<br>||style="background:#FCC"|NOP<br>d||style="background:#FCC"|PLA<br>||style="background:#FCC"|JMP<br>(a)||style="background:#FCC"|BVS<br>*+d||style="background:#FCC"|NOP<br>d,x||style="background:#FCC"|SEI<br>||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|ADC<br>(d,x)||style="background:#CFC"|ADC<br>d||style="background:#CFC"|ADC<br>#i||style="background:#CFC"|ADC<br>a||style="background:#CFC"|ADC<br>(d),y||style="background:#CFC"|ADC<br>d,x||style="background:#CFC"|ADC<br>a,y||style="background:#CFC"|ADC<br>a,x||style="background:#CCF"|KIL<br>||style="background:#CCF"|ROR<br>d||style="background:#CCF"|ROR<br>||style="background:#CCF"|ROR<br>a||style="background:#CCF"|KIL<br>||style="background:#CCF"|ROR<br>d,x||style="background:#CCF"|NOP<br>||style="background:#CCF"|ROR<br>a,x||style="background:#DDD"|RRA<br>(d,x)||style="background:#DDD"|RRA<br>d||style="background:#DDD"|ARR<br>#i||style="background:#DDD"|RRA<br>a||style="background:#DDD"|RRA<br>(d),y||style="background:#DDD"|RRA<br>d,x||style="background:#DDD"|RRA<br>a,y||style="background:#DDD"|RRA<br>a,x
|60||style="background:#FCC"|RTS<br>||style="background:#FCC"|'''NOP'''<br>d||style="background:#FCC"|PLA<br>||style="background:#FCC"|JMP<br>(a)||style="background:#FCC"|BVS<br>*+d||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#FCC"|SEI<br>||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|ADC<br>(d,x)||style="background:#CFC"|ADC<br>d||style="background:#CFC"|ADC<br>#i||style="background:#CFC"|ADC<br>a||style="background:#CFC"|ADC<br>(d),y||style="background:#CFC"|ADC<br>d,x||style="background:#CFC"|ADC<br>a,y||style="background:#CFC"|ADC<br>a,x||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|ROR<br>d||style="background:#CCF"|ROR<br>||style="background:#CCF"|ROR<br>a||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|ROR<br>d,x||style="background:#CCF"|'''NOP'''<br>||style="background:#CCF"|ROR<br>a,x||style="background:#DDD"|'''RRA'''<br>(d,x)||style="background:#DDD"|'''RRA'''<br>d||style="background:#DDD"|'''ARR'''<br>#i||style="background:#DDD"|'''RRA'''<br>a||style="background:#DDD"|'''RRA'''<br>(d),y||style="background:#DDD"|'''RRA'''<br>d,x||style="background:#DDD"|'''RRA'''<br>a,y||style="background:#DDD"|'''RRA'''<br>a,x
|- valign="top"
|- valign="top"
|80||style="background:#FCC"|NOP<br>#i||style="background:#FCC"|STY<br>d||style="background:#FCC"|DEY<br>||style="background:#FCC"|STY<br>a||style="background:#FCC"|BCC<br>*+d||style="background:#FCC"|STY<br>d,x||style="background:#FCC"|TYA<br>||style="background:#FCC"|SHY<br>a,x||style="background:#CFC"|STA<br>(d,x)||style="background:#CFC"|STA<br>d||style="background:#CFC"|NOP<br>#i||style="background:#CFC"|STA<br>a||style="background:#CFC"|STA<br>(d),y||style="background:#CFC"|STA<br>d,x||style="background:#CFC"|STA<br>a,y||style="background:#CFC"|STA<br>a,x||style="background:#CCF"|NOP<br>#i||style="background:#CCF"|STX<br>d||style="background:#CCF"|TXA<br>||style="background:#CCF"|STX<br>a||style="background:#CCF"|KIL<br>||style="background:#CCF"|STX<br>d,y||style="background:#CCF"|TXS<br>||style="background:#CCF"|SHX<br>a,y||style="background:#DDD"|SAX<br>(d,x)||style="background:#DDD"|SAX<br>d||style="background:#DDD"|XAA<br>#i||style="background:#DDD"|SAX<br>a||style="background:#DDD"|AHX<br>(d),y||style="background:#DDD"|SAX<br>d,y||style="background:#DDD"|TAS<br>a,y||style="background:#DDD"|AHX<br>a,y
|80||style="background:#FCC"|'''NOP'''<br>#i||style="background:#FCC"|STY<br>d||style="background:#FCC"|DEY<br>||style="background:#FCC"|STY<br>a||style="background:#FCC"|BCC<br>*+d||style="background:#FCC"|STY<br>d,x||style="background:#FCC"|TYA<br>||style="background:#FCC"|'''SHY'''<br>a,x||style="background:#CFC"|STA<br>(d,x)||style="background:#CFC"|STA<br>d||style="background:#CFC"|'''NOP'''<br>#i||style="background:#CFC"|STA<br>a||style="background:#CFC"|STA<br>(d),y||style="background:#CFC"|STA<br>d,x||style="background:#CFC"|STA<br>a,y||style="background:#CFC"|STA<br>a,x||style="background:#CCF"|'''NOP'''<br>#i||style="background:#CCF"|STX<br>d||style="background:#CCF"|TXA<br>||style="background:#CCF"|STX<br>a||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|STX<br>d,y||style="background:#CCF"|TXS<br>||style="background:#CCF"|'''SHX'''<br>a,y||style="background:#DDD"|'''SAX'''<br>(d,x)||style="background:#DDD"|'''SAX'''<br>d||style="background:#DDD"|'''XAA'''<br>#i||style="background:#DDD"|'''SAX'''<br>a||style="background:#DDD"|'''AHX'''<br>(d),y||style="background:#DDD"|'''SAX'''<br>d,y||style="background:#DDD"|'''TAS'''<br>a,y||style="background:#DDD"|'''AHX'''<br>a,y
|- valign="top"
|- valign="top"
|A0||style="background:#FCC"|LDY<br>#i||style="background:#FCC"|LDY<br>d||style="background:#FCC"|TAY<br>||style="background:#FCC"|LDY<br>a||style="background:#FCC"|BCS<br>*+d||style="background:#FCC"|LDY<br>d,x||style="background:#FCC"|CLV<br>||style="background:#FCC"|LDY<br>a,x||style="background:#CFC"|LDA<br>(d,x)||style="background:#CFC"|LDA<br>d||style="background:#CFC"|LDA<br>#i||style="background:#CFC"|LDA<br>a||style="background:#CFC"|LDA<br>(d),y||style="background:#CFC"|LDA<br>d,x||style="background:#CFC"|LDA<br>a,y||style="background:#CFC"|LDA<br>a,x||style="background:#CCF"|LDX<br>#i||style="background:#CCF"|LDX<br>d||style="background:#CCF"|TAX<br>||style="background:#CCF"|LDX<br>a||style="background:#CCF"|KIL<br>||style="background:#CCF"|LDX<br>d,y||style="background:#CCF"|TSX<br>||style="background:#CCF"|LDX<br>a,y||style="background:#DDD"|LAX<br>(d,x)||style="background:#DDD"|LAX<br>d||style="background:#DDD"|LAX<br>#i||style="background:#DDD"|LAX<br>a||style="background:#DDD"|LAX<br>(d),y||style="background:#DDD"|LAX<br>d,y||style="background:#DDD"|LAS<br>a,y||style="background:#DDD"|LAX<br>a,y
|A0||style="background:#FCC"|LDY<br>#i||style="background:#FCC"|LDY<br>d||style="background:#FCC"|TAY<br>||style="background:#FCC"|LDY<br>a||style="background:#FCC"|BCS<br>*+d||style="background:#FCC"|LDY<br>d,x||style="background:#FCC"|CLV<br>||style="background:#FCC"|LDY<br>a,x||style="background:#CFC"|LDA<br>(d,x)||style="background:#CFC"|LDA<br>d||style="background:#CFC"|LDA<br>#i||style="background:#CFC"|LDA<br>a||style="background:#CFC"|LDA<br>(d),y||style="background:#CFC"|LDA<br>d,x||style="background:#CFC"|LDA<br>a,y||style="background:#CFC"|LDA<br>a,x||style="background:#CCF"|LDX<br>#i||style="background:#CCF"|LDX<br>d||style="background:#CCF"|TAX<br>||style="background:#CCF"|LDX<br>a||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|LDX<br>d,y||style="background:#CCF"|TSX<br>||style="background:#CCF"|LDX<br>a,y||style="background:#DDD"|'''LAX'''<br>(d,x)||style="background:#DDD"|'''LAX'''<br>d||style="background:#DDD"|'''LAX'''<br>#i||style="background:#DDD"|'''LAX'''<br>a||style="background:#DDD"|'''LAX'''<br>(d),y||style="background:#DDD"|'''LAX'''<br>d,y||style="background:#DDD"|'''LAS'''<br>a,y||style="background:#DDD"|'''LAX'''<br>a,y
|- valign="top"
|- valign="top"
|C0||style="background:#FCC"|CPY<br>#i||style="background:#FCC"|CPY<br>d||style="background:#FCC"|INY<br>||style="background:#FCC"|CPY<br>a||style="background:#FCC"|BNE<br>*+d||style="background:#FCC"|NOP<br>d,x||style="background:#FCC"|CLD<br>||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|CMP<br>(d,x)||style="background:#CFC"|CMP<br>d||style="background:#CFC"|CMP<br>#i||style="background:#CFC"|CMP<br>a||style="background:#CFC"|CMP<br>(d),y||style="background:#CFC"|CMP<br>d,x||style="background:#CFC"|CMP<br>a,y||style="background:#CFC"|CMP<br>a,x||style="background:#CCF"|NOP<br>#i||style="background:#CCF"|DEC<br>d||style="background:#CCF"|DEX<br>||style="background:#CCF"|DEC<br>a||style="background:#CCF"|KIL<br>||style="background:#CCF"|DEC<br>d,x||style="background:#CCF"|NOP<br>||style="background:#CCF"|DEC<br>a,x||style="background:#DDD"|DCP<br>(d,x)||style="background:#DDD"|DCP<br>d||style="background:#DDD"|AXS<br>#i||style="background:#DDD"|DCP<br>a||style="background:#DDD"|DCP<br>(d),y||style="background:#DDD"|DCP<br>d,x||style="background:#DDD"|DCP<br>a,y||style="background:#DDD"|DCP<br>a,x
|C0||style="background:#FCC"|CPY<br>#i||style="background:#FCC"|CPY<br>d||style="background:#FCC"|INY<br>||style="background:#FCC"|CPY<br>a||style="background:#FCC"|BNE<br>*+d||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#FCC"|CLD<br>||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|CMP<br>(d,x)||style="background:#CFC"|CMP<br>d||style="background:#CFC"|CMP<br>#i||style="background:#CFC"|CMP<br>a||style="background:#CFC"|CMP<br>(d),y||style="background:#CFC"|CMP<br>d,x||style="background:#CFC"|CMP<br>a,y||style="background:#CFC"|CMP<br>a,x||style="background:#CCF"|'''NOP'''<br>#i||style="background:#CCF"|DEC<br>d||style="background:#CCF"|DEX<br>||style="background:#CCF"|DEC<br>a||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|DEC<br>d,x||style="background:#CCF"|'''NOP'''<br>||style="background:#CCF"|DEC<br>a,x||style="background:#DDD"|'''DCP'''<br>(d,x)||style="background:#DDD"|'''DCP'''<br>d||style="background:#DDD"|'''AXS'''<br>#i||style="background:#DDD"|'''DCP'''<br>a||style="background:#DDD"|'''DCP'''<br>(d),y||style="background:#DDD"|'''DCP'''<br>d,x||style="background:#DDD"|'''DCP'''<br>a,y||style="background:#DDD"|'''DCP'''<br>a,x
|- valign="top"
|- valign="top"
|E0||style="background:#FCC"|CPX<br>#i||style="background:#FCC"|CPX<br>d||style="background:#FCC"|INX<br>||style="background:#FCC"|CPX<br>a||style="background:#FCC"|BEQ<br>*+d||style="background:#FCC"|NOP<br>d,x||style="background:#FCC"|SED<br>||style="background:#FCC"|NOP<br>a,x||style="background:#CFC"|SBC<br>(d,x)||style="background:#CFC"|SBC<br>d||style="background:#CFC"|SBC<br>#i||style="background:#CFC"|SBC<br>a||style="background:#CFC"|SBC<br>(d),y||style="background:#CFC"|SBC<br>d,x||style="background:#CFC"|SBC<br>a,y||style="background:#CFC"|SBC<br>a,x||style="background:#CCF"|NOP<br>#i||style="background:#CCF"|INC<br>d||style="background:#CCF"|NOP<br>||style="background:#CCF"|INC<br>a||style="background:#CCF"|KIL<br>||style="background:#CCF"|INC<br>d,x||style="background:#CCF"|NOP<br>||style="background:#CCF"|INC<br>a,x||style="background:#DDD"|ISC<br>(d,x)||style="background:#DDD"|ISC<br>d||style="background:#DDD"|SBC<br>#i||style="background:#DDD"|ISC<br>a||style="background:#DDD"|ISC<br>(d),y||style="background:#DDD"|ISC<br>d,x||style="background:#DDD"|ISC<br>a,y||style="background:#DDD"|ISC<br>a,x
|E0||style="background:#FCC"|CPX<br>#i||style="background:#FCC"|CPX<br>d||style="background:#FCC"|INX<br>||style="background:#FCC"|CPX<br>a||style="background:#FCC"|BEQ<br>*+d||style="background:#FCC"|'''NOP'''<br>d,x||style="background:#FCC"|SED<br>||style="background:#FCC"|'''NOP'''<br>a,x||style="background:#CFC"|SBC<br>(d,x)||style="background:#CFC"|SBC<br>d||style="background:#CFC"|SBC<br>#i||style="background:#CFC"|SBC<br>a||style="background:#CFC"|SBC<br>(d),y||style="background:#CFC"|SBC<br>d,x||style="background:#CFC"|SBC<br>a,y||style="background:#CFC"|SBC<br>a,x||style="background:#CCF"|'''NOP'''<br>#i||style="background:#CCF"|INC<br>d||style="background:#CCF"|NOP<br>||style="background:#CCF"|INC<br>a||style="background:#CCF"|'''STP'''<br>||style="background:#CCF"|INC<br>d,x||style="background:#CCF"|'''NOP'''<br>||style="background:#CCF"|INC<br>a,x||style="background:#DDD"|'''ISC'''<br>(d,x)||style="background:#DDD"|'''ISC'''<br>d||style="background:#DDD"|'''SBC'''<br>#i||style="background:#DDD"|'''ISC'''<br>a||style="background:#DDD"|'''ISC'''<br>(d),y||style="background:#DDD"|'''ISC'''<br>d,x||style="background:#DDD"|'''ISC'''<br>a,y||style="background:#DDD"|'''ISC'''<br>a,x
|}
|}


Line 71: Line 78:
Column +0B, on the other hand, has no extra cycles; everything completes during the next opcode's fetch.
Column +0B, on the other hand, has no extra cycles; everything completes during the next opcode's fetch.
This causes instructions to have strange mixing properties.
This causes instructions to have strange mixing properties.
Some even [http://visual6502.org/wiki/index.php?title=6502_Opcode_8B_%28XAA,_ANE%29 differ based on analog effects].
Some even [[visual6502wiki/6502_Opcode_8B_%28XAA,_ANE%29|differ based on analog effects]].


== Games using unofficial opcodes ==
== Games using unofficial opcodes ==
Later extensions to the 6502 family (65C02, HuC6280, 65C816) replaced some of these unofficial opcodes with different opcodes.
 
It's conjectured that Nintendo banned the use of unofficial opcodes in NES games that would make the games incompatible with these one of these CPUs in an upgraded NES.
The use of unofficial opcodes is rare in NES games. It appears to occur mostly in late or unlicensed titles:
But as it became clear that the Super NES was not going to be backward compatible, Nintendo may have eased up on this for later titles.
 
*''Puzznic'' (all regions) (US release November 1990) uses $89, which is a 2-byte NOP on 6502 and BIT #imm on 65C02 and later, and [http://tasvideos.org/forum/viewtopic.php?p=306520#306520 emulating it as a single-byte NOP will break it]. That'd be expected in a port from a 65C02 game, but the arcade version uses the Z80 of Taito's L System according to [http://www.system16.com/hardware.php?id=654 System 16] and [http://mamedev.org/source/src/mame/drivers/taito_l.c.html MAME]. Does it share code with the PC Engine port or something?
*''Beauty and the Beast'' (E) (1994) uses <tt>$80</tt> (a 2-byte NOP).<ref>[http://forums.nesdev.org/viewtopic.php?f=3&t=6928 puNES 0.20 changelog] indicating $80 opcode in ''Beauty and the Beast''.</ref>
*''Beauty and the Beast'' (E) (1994) uses a different SKB ($80), which is BRA on 65C02. (source: [http://forums.nesdev.org/viewtopic.php?f=3&t=6928 puNES 0.20 changelog])
*''Disney's Aladdin'' (E) (December 1994) uses <tt>$07</tt> (SLO). This is Virgin's port of the Game Boy game, itself a port of the Genesis game, not any of the [https://bootleggames.fandom.com/wiki/Special:PrefixIndex/Aladdin pirate originals].
*''Super Cars'' (U) (February 1991) uses LAX
*''Dynowarz: Destruction of Spondylus'' (April 1990) uses 1-byte NOPs <tt>$DA</tt> and <tt>$FA</tt> on the first level when your dino throws his fist.
*''Disney's Aladdin'' (E) (December 1994) uses SLO. This is Virgin's port of the Game Boy game, itself a port of the Genesis game, not any of the [[wikia:c:bootleggames:Special:PrefixIndex/Aladdin|pirate originals]].
*''F-117A Stealth Fighter'' uses <tt>$89</tt> (a 2-byte NOP).
As hobbyists became aware of what these instructions could do, homebrew games started to use them:
*''文字广场+排雷'' (romanized in GoodNES as Cantonese "Gaau Hok Gwong Cheung (Ch)"): After selecting the left game (排雷) from this 2-in-1 multicart, a glitchy [[INES Mapper 242|32 KiB bankswitch]] causes the CPU to get lost in non-code ROM space that only with correct emulation of unofficial opcodes, including $8B (XAA immediate), will have it eventually reach a BRK instruction that properly branches to that game's reset handler.
*The MUSE music engine, used in ''Driar'' and ''STREEMERZ: Super Strength Emergency Squad Zeta'', uses the unofficial opcodes $8F (SAX), $B3 (LAX), and $CB (AXS) [http://forums.nesdev.org/viewtopic.php?p=100957#p100957]
*''Infiltrator'' uses <tt>$89</tt> (a 2-byte NOP).
*''Puzznic'' (all regions) (US release November 1990) uses <tt>$89</tt> (a 2-byte NOP).
*''Super Cars'' (U) (February 1991) uses <tt>$B3</tt> (LAX).
 
=== Homebrew games ===
 
*The MUSE music engine, used in ''Driar'' and ''STREEMERZ: Super Strength Emergency Squad Zeta'', uses <tt>$8F</tt> (SAX), <tt>$B3</tt> (LAX), and <tt>$CB</tt> (AXS).<ref>http://forums.nesdev.org/viewtopic.php?p=100957#p100957</ref>
*''[[User:Zzo38/Attribute Zone|Attribute Zone]]'' uses <tt>$0B</tt> (ANC), <tt>$2F</tt> (RLA), <tt>$4B</tt> (ALR), <tt>$A7</tt> (LAX), <tt>$B3</tt> (LAX), <tt>$CB</tt> (AXS), <tt>$D3</tt> (DCP) and <tt>$DB</tt> (DCP).
*The port of ''Zork'' to the Famicom uses a few unofficial opcodes.
* ''Eyra, the Crow Maiden'' uses several unofficial opcodes.


== See also ==
== See also ==
Line 88: Line 104:


== External links ==
== External links ==
*[http://www.oxyron.de/html/opcodes02.html 6502 opcode matrix including unofficial opcodes]; compare
*[http://www.oxyron.de/html/opcodes02.html 6502 opcode matrix including unofficial opcodes]
*[http://www.oxyron.de/html/opcodesc02.html 65C02] and [http://www.oxyron.de/html/opcodes816.html 65816]
*[http://www.oxyron.de/html/opcodesc02.html 65C02] and [http://www.oxyron.de/html/opcodes816.html 65816]
*[[wikipedia:Illegal opcode|Illegal opcodes]] at Wikipedia.
* [http://www.romhacking.net/documents/318/ 65xx Processor Data]
* [http://nesdev.org/6502_cpu.txt 6502_cpu.txt]
== References ==
<references/>

Latest revision as of 22:15, 4 July 2023

Unofficial opcodes, sometimes called illegal opcodes or undocumented opcodes, are CPU instructions that were officially left unused by the original design. The 6502 family datasheet from MOS Technology does not specify or document their function, but they actually do perform various operations.

Some of these instructions are useful; some are not predictable; some do nothing but burn cycles; some halt the CPU until reset. Most NMOS 6502 cores interpret them the same way, although there are slight differences with the less stable instructions. CMOS variants of the 6502 handle them completely differently, and later CPUs in the same family (e.g. 65C02, HuC6280, 65C816) were free to implement new instructions in the place of the unused ones.

An accurate NES emulator must implement all instructions, not just the official ones. A small number of games use them (see below).

Arrangement

The microcode of the 6502 is compressed into a 130-entry decode ROM. Instead of 256 entries telling how to process each separate opcode, it's encoded as combinational logic post-processing the output of a "sparse" ROM that acts in some ways like a programmable logic array (PLA). Each entry in the ROM means "if these bits are on, and these bits are off, do things on these six cycles."[1]

Many instructions activate multiple lines of the decode ROM at once. Often this is on purpose, such as one line for the addressing mode and one for the opcode part. But many of the unofficial opcodes simultaneously trigger parts of the ROM that were intended for completely unrelated instructions.

Perhaps the pattern is easier to see by shuffling the 6502's opcode matrix. This table lists all 6502 opcodes, 32 columns per row. The columns are colored by bits 1 and 0: 00 red, 01 green, 10 blue, and 11 gray.

+00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0A +0B +0C +0D +0E +0F +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +1A +1B +1C +1D +1E +1F
00 BRK
ORA
(d,x)
STP
SLO
(d,x)
NOP
d
ORA
d
ASL
d
SLO
d
PHP
ORA
#i
ASL
ANC
#i
NOP
a
ORA
a
ASL
a
SLO
a
BPL
*+d
ORA
(d),y
STP
SLO
(d),y
NOP
d,x
ORA
d,x
ASL
d,x
SLO
d,x
CLC
ORA
a,y
NOP
SLO
a,y
NOP
a,x
ORA
a,x
ASL
a,x
SLO
a,x
20 JSR
a
AND
(d,x)
STP
RLA
(d,x)
BIT
d
AND
d
ROL
d
RLA
d
PLP
AND
#i
ROL
ANC
#i
BIT
a
AND
a
ROL
a
RLA
a
BMI
*+d
AND
(d),y
STP
RLA
(d),y
NOP
d,x
AND
d,x
ROL
d,x
RLA
d,x
SEC
AND
a,y
NOP
RLA
a,y
NOP
a,x
AND
a,x
ROL
a,x
RLA
a,x
40 RTI
EOR
(d,x)
STP
SRE
(d,x)
NOP
d
EOR
d
LSR
d
SRE
d
PHA
EOR
#i
LSR
ALR
#i
JMP
a
EOR
a
LSR
a
SRE
a
BVC
*+d
EOR
(d),y
STP
SRE
(d),y
NOP
d,x
EOR
d,x
LSR
d,x
SRE
d,x
CLI
EOR
a,y
NOP
SRE
a,y
NOP
a,x
EOR
a,x
LSR
a,x
SRE
a,x
60 RTS
ADC
(d,x)
STP
RRA
(d,x)
NOP
d
ADC
d
ROR
d
RRA
d
PLA
ADC
#i
ROR
ARR
#i
JMP
(a)
ADC
a
ROR
a
RRA
a
BVS
*+d
ADC
(d),y
STP
RRA
(d),y
NOP
d,x
ADC
d,x
ROR
d,x
RRA
d,x
SEI
ADC
a,y
NOP
RRA
a,y
NOP
a,x
ADC
a,x
ROR
a,x
RRA
a,x
80 NOP
#i
STA
(d,x)
NOP
#i
SAX
(d,x)
STY
d
STA
d
STX
d
SAX
d
DEY
NOP
#i
TXA
XAA
#i
STY
a
STA
a
STX
a
SAX
a
BCC
*+d
STA
(d),y
STP
AHX
(d),y
STY
d,x
STA
d,x
STX
d,y
SAX
d,y
TYA
STA
a,y
TXS
TAS
a,y
SHY
a,x
STA
a,x
SHX
a,y
AHX
a,y
A0 LDY
#i
LDA
(d,x)
LDX
#i
LAX
(d,x)
LDY
d
LDA
d
LDX
d
LAX
d
TAY
LDA
#i
TAX
LAX
#i
LDY
a
LDA
a
LDX
a
LAX
a
BCS
*+d
LDA
(d),y
STP
LAX
(d),y
LDY
d,x
LDA
d,x
LDX
d,y
LAX
d,y
CLV
LDA
a,y
TSX
LAS
a,y
LDY
a,x
LDA
a,x
LDX
a,y
LAX
a,y
C0 CPY
#i
CMP
(d,x)
NOP
#i
DCP
(d,x)
CPY
d
CMP
d
DEC
d
DCP
d
INY
CMP
#i
DEX
AXS
#i
CPY
a
CMP
a
DEC
a
DCP
a
BNE
*+d
CMP
(d),y
STP
DCP
(d),y
NOP
d,x
CMP
d,x
DEC
d,x
DCP
d,x
CLD
CMP
a,y
NOP
DCP
a,y
NOP
a,x
CMP
a,x
DEC
a,x
DCP
a,x
E0 CPX
#i
SBC
(d,x)
NOP
#i
ISC
(d,x)
CPX
d
SBC
d
INC
d
ISC
d
INX
SBC
#i
NOP
SBC
#i
CPX
a
SBC
a
INC
a
ISC
a
BEQ
*+d
SBC
(d),y
STP
ISC
(d),y
NOP
d,x
SBC
d,x
INC
d,x
ISC
d,x
SED
SBC
a,y
NOP
ISC
a,y
NOP
a,x
SBC
a,x
INC
a,x
ISC
a,x

Key: a is a 16-bit absolute address, and d is an 8-bit zero page address. Entries in bold represent unofficial opcodes.

But if we rearrange it so that columns with the same bits 1-0 are close together, correlations become easier to see:

+00 +04 +08 +0C +10 +14 +18 +1C +01 +05 +09 +0D +11 +15 +19 +1D +02 +06 +0A +0E +12 +16 +1A +1E +03 +07 +0B +0F +13 +17 +1B +1F
00 BRK
NOP
d
PHP
NOP
a
BPL
*+d
NOP
d,x
CLC
NOP
a,x
ORA
(d,x)
ORA
d
ORA
#i
ORA
a
ORA
(d),y
ORA
d,x
ORA
a,y
ORA
a,x
STP
ASL
d
ASL
ASL
a
STP
ASL
d,x
NOP
ASL
a,x
SLO
(d,x)
SLO
d
ANC
#i
SLO
a
SLO
(d),y
SLO
d,x
SLO
a,y
SLO
a,x
20 JSR
a
BIT
d
PLP
BIT
a
BMI
*+d
NOP
d,x
SEC
NOP
a,x
AND
(d,x)
AND
d
AND
#i
AND
a
AND
(d),y
AND
d,x
AND
a,y
AND
a,x
STP
ROL
d
ROL
ROL
a
STP
ROL
d,x
NOP
ROL
a,x
RLA
(d,x)
RLA
d
ANC
#i
RLA
a
RLA
(d),y
RLA
d,x
RLA
a,y
RLA
a,x
40 RTI
NOP
d
PHA
JMP
a
BVC
*+d
NOP
d,x
CLI
NOP
a,x
EOR
(d,x)
EOR
d
EOR
#i
EOR
a
EOR
(d),y
EOR
d,x
EOR
a,y
EOR
a,x
STP
LSR
d
LSR
LSR
a
STP
LSR
d,x
NOP
LSR
a,x
SRE
(d,x)
SRE
d
ALR
#i
SRE
a
SRE
(d),y
SRE
d,x
SRE
a,y
SRE
a,x
60 RTS
NOP
d
PLA
JMP
(a)
BVS
*+d
NOP
d,x
SEI
NOP
a,x
ADC
(d,x)
ADC
d
ADC
#i
ADC
a
ADC
(d),y
ADC
d,x
ADC
a,y
ADC
a,x
STP
ROR
d
ROR
ROR
a
STP
ROR
d,x
NOP
ROR
a,x
RRA
(d,x)
RRA
d
ARR
#i
RRA
a
RRA
(d),y
RRA
d,x
RRA
a,y
RRA
a,x
80 NOP
#i
STY
d
DEY
STY
a
BCC
*+d
STY
d,x
TYA
SHY
a,x
STA
(d,x)
STA
d
NOP
#i
STA
a
STA
(d),y
STA
d,x
STA
a,y
STA
a,x
NOP
#i
STX
d
TXA
STX
a
STP
STX
d,y
TXS
SHX
a,y
SAX
(d,x)
SAX
d
XAA
#i
SAX
a
AHX
(d),y
SAX
d,y
TAS
a,y
AHX
a,y
A0 LDY
#i
LDY
d
TAY
LDY
a
BCS
*+d
LDY
d,x
CLV
LDY
a,x
LDA
(d,x)
LDA
d
LDA
#i
LDA
a
LDA
(d),y
LDA
d,x
LDA
a,y
LDA
a,x
LDX
#i
LDX
d
TAX
LDX
a
STP
LDX
d,y
TSX
LDX
a,y
LAX
(d,x)
LAX
d
LAX
#i
LAX
a
LAX
(d),y
LAX
d,y
LAS
a,y
LAX
a,y
C0 CPY
#i
CPY
d
INY
CPY
a
BNE
*+d
NOP
d,x
CLD
NOP
a,x
CMP
(d,x)
CMP
d
CMP
#i
CMP
a
CMP
(d),y
CMP
d,x
CMP
a,y
CMP
a,x
NOP
#i
DEC
d
DEX
DEC
a
STP
DEC
d,x
NOP
DEC
a,x
DCP
(d,x)
DCP
d
AXS
#i
DCP
a
DCP
(d),y
DCP
d,x
DCP
a,y
DCP
a,x
E0 CPX
#i
CPX
d
INX
CPX
a
BEQ
*+d
NOP
d,x
SED
NOP
a,x
SBC
(d,x)
SBC
d
SBC
#i
SBC
a
SBC
(d),y
SBC
d,x
SBC
a,y
SBC
a,x
NOP
#i
INC
d
NOP
INC
a
STP
INC
d,x
NOP
INC
a,x
ISC
(d,x)
ISC
d
SBC
#i
ISC
a
ISC
(d),y
ISC
d,x
ISC
a,y
ISC
a,x

Thus the 00 (red) block is mostly control instructions, 01 (green) is ALU operations, and 10 (blue) is read-modify-write (RMW) operations and data movement instructions involving X. The RMW instructions (all but row 80 and A0) in columns +06, +0E, +16, and +1E have the same addressing modes as the corresponding ALU operations.

The 11 (gray) block is unofficial opcodes combining the operations of instructions from the ALU and RMW blocks. all of them having the same addressing mode as the corresponding ALU opcode. The RMW+ALU instructions that affect memory are easiest to understand because their RMW part completes during the opcode and the ALU part completes during the next opcode's fetch. Column +0B, on the other hand, has no extra cycles; everything completes during the next opcode's fetch. This causes instructions to have strange mixing properties. Some even differ based on analog effects.

Games using unofficial opcodes

The use of unofficial opcodes is rare in NES games. It appears to occur mostly in late or unlicensed titles:

  • Beauty and the Beast (E) (1994) uses $80 (a 2-byte NOP).[2]
  • Disney's Aladdin (E) (December 1994) uses $07 (SLO). This is Virgin's port of the Game Boy game, itself a port of the Genesis game, not any of the pirate originals.
  • Dynowarz: Destruction of Spondylus (April 1990) uses 1-byte NOPs $DA and $FA on the first level when your dino throws his fist.
  • F-117A Stealth Fighter uses $89 (a 2-byte NOP).
  • 文字广场+排雷 (romanized in GoodNES as Cantonese "Gaau Hok Gwong Cheung (Ch)"): After selecting the left game (排雷) from this 2-in-1 multicart, a glitchy 32 KiB bankswitch causes the CPU to get lost in non-code ROM space that only with correct emulation of unofficial opcodes, including $8B (XAA immediate), will have it eventually reach a BRK instruction that properly branches to that game's reset handler.
  • Infiltrator uses $89 (a 2-byte NOP).
  • Puzznic (all regions) (US release November 1990) uses $89 (a 2-byte NOP).
  • Super Cars (U) (February 1991) uses $B3 (LAX).

Homebrew games

  • The MUSE music engine, used in Driar and STREEMERZ: Super Strength Emergency Squad Zeta, uses $8F (SAX), $B3 (LAX), and $CB (AXS).[3]
  • Attribute Zone uses $0B (ANC), $2F (RLA), $4B (ALR), $A7 (LAX), $B3 (LAX), $CB (AXS), $D3 (DCP) and $DB (DCP).
  • The port of Zork to the Famicom uses a few unofficial opcodes.
  • Eyra, the Crow Maiden uses several unofficial opcodes.

See also

External links

References

  1. Michael Steil. "How MOS 6502 Illegal Opcodes really work". Pagetable, 2008-07-29. Accessed 2019-11-10.
  2. puNES 0.20 changelog indicating $80 opcode in Beauty and the Beast.
  3. http://forums.nesdev.org/viewtopic.php?p=100957#p100957