CPU unofficial opcodes: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(I'm working on an article about the unofficial opcodes that are most useful to programmers)
(How 11-suffix unofficial ops work)
Line 9: Line 9:
Some instructions trip multiple PLA lines at once.
Some instructions trip multiple PLA lines at once.


Later extensions to the 6502 family (65C02, Hu6280, 65C816) replaced some of these undocumented opcodes with different opcodes.
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
|- 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
|- 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
|- 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
|- 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
|- 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
|- 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
|- 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
|- 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
|}
 
Key: a is a 16-bit absolute address, and d is an 8-bit zero page address.
 
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
|- 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
|- 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
|- 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
|- 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
|- 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
|- 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
|- 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
|- 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
|}
 
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 [http://visual6502.org/wiki/index.php?title=6502_Opcode_8B_%28XAA,_ANE%29 differ based on analog effects].
 
Later extensions to the 6502 family (65C02, Hu6280, 65C816) replaced some of these unofficial opcodes with different opcodes.


== See also ==
== See also ==
*[[Programming with unofficial opcodes]]
*[[Programming with unofficial opcodes]]
== External links ==
*[http://www.oxyron.de/html/opcodes02.html 6502 opcode matrix including unofficial opcodes]

Revision as of 01:45, 1 May 2012

"This is illegal, you know."

Kravindish, Mayor of Sakado, Zelda: The Wand of Gamelon

Unofficial opcodes, sometimes misleadingly called 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 halt the CPU until reset. Most 6502 cores interpret them the same way, although there are slight differences.

The microcode of the 6502 is compressed. 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." [1] Some instructions trip multiple PLA lines at once.

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)
KIL
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
KIL
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)
KIL
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
KIL
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)
KIL
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
KIL
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)
KIL
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
KIL
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
KIL
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
KIL
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
KIL
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
KIL
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.

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
KIL
ASL
d
ASL
ASL
a
KIL
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
KIL
ROL
d
ROL
ROL
a
KIL
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
KIL
LSR
d
LSR
LSR
a
KIL
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
KIL
ROR
d
ROR
ROR
a
KIL
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
KIL
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
KIL
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
KIL
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
KIL
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.

Later extensions to the 6502 family (65C02, Hu6280, 65C816) replaced some of these unofficial opcodes with different opcodes.

See also

External links