6502 Undocumented Opcodes =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= Based on the Atari 8-bit 6502 Version 3.0, 5/17/1997 By Freddy Offenga (offen300@hio.tem.nhl.nl) This version is a direct follow up of the illegal opcode list by Joakim Atterhal (WosFilm) and me which was published in the Atari 8-bit disk magazine "Mega Maga-zine" issue #6. Most opcode names in this list originated from a disassembler for the Atari (The Symbolic Disas-sem-bler by HiasSoft). Credits: - Joakim Atterhal - Adam Vardy - Craig Taylor References: 1. Illegal opcodes, WosFilm and Frankenstein, Mega Magazine #2, December 1991 2. Illegal opcodes v2, WosFilm and Fran-ken-stein, Mega Maga-zine #6, October 1993 3. Illegal Opcodes der 65xx-CPU, Frank Leiprecht, ABBUC Sondermagazin 10, Top-Maga-zin Oktober 1991 4. Erg=E4nzung zu den Illegalen OP-Codes, Peter W=F6tzel, Top-M-ag-azin Januar 1992. 5. 6502 Opcodes and Quasi-Opcodes, Craig Taylor, 1992 6. Extra Instructions Of The 65XX Series CPU, Adam Vardy, 27 Sept. 1996 Changes since Version 2.0: Version 2.0 was compared with two Commodore 8-bit based lists found on the inter-net. There were some diffe-rences in opcode names, so I included the other names too. Names between curly brackets are the names taken from the list compiled by Craig Taylor. Names between square brackets are the names taken from the list by Adam Vardy. The old list was also compared with two other Atari 8-bit based lists (by Frank Leiprecht and Peter W=F6tzel). No new things were found on thes= e lists. The timing values (clock cycles) from all the opcodes were compared with the values on the list by Adam Vardy. There were no differen-ces. The addressing modes for the "DOP" (double nop) and "TOP" instructions were copied from Craig Taylor's list. The reason for this is that the different addressing modes explain the differences in the timing values. Opcode $8B was removed from the "AAX" table. The behaviour of this opcode seems to be comlex (as noted by several peop-le). Maybe there will be more information in the next version of this document. For now this opcode is called "XAA". The addressing mode for opcode $A3 (LAX) was false on the previous list. Changed to (indi-rect,x). The addressing modes for opcodes $13 and $03 (SLO) were swit-ched. Corrected in this version. Addressing mode for opcode $B7 (LAX) was "zero-page,x", but should be "zero-page,y". Corrected. Changed the suspicious opcode $93. This one was called "DOP", but is in fact another "AXA" instruction. Tested the behaviour of $9E (SXA), $9C (SYA) and $9B (XAS). There static AND with 7 mentioned in the old list was false. The observation of the function 'AND with the high byte of the argument + 1' (from Adam Vardy's list) seems to be correct. Opc : opcode in hexadecimal Sz : size in bytes n : number of clock cycles * : add one cycle when page boundary is crossed AAC (ANC) [ANC] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND byte with accumulator. If result is negative then carry is set. Status flags: N,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Immediate |AAC #arg |$0B| 2 | 2 Immediate |AAC #arg |$2B| 2 | 2 AAX (SAX) [AXS] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND X register with accumulator and store result in memory. Status flags: N,Z Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |AAX arg |$87| 2 | 3 Zero Page,Y |AAX arg,Y |$97| 2 | 4 (Indirect,X)|AAX (arg,X)|$83| 2 | 6 Absolute |AAX arg |$8F| 3 | 4 ARR (ARR) [ARR] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND byte with accumulator, then rotate one bit right in accu-mulator and check bit 5 and 6: If both bits are 1: set C, clear V. If both bits are 0: clear C and V. If only bit 5 is 1: set V, clear C. If only bit 6 is 1: set C and V. Status flags: N,V,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Immediate |ARR #arg |$6B| 2 | 2 ASR (ASR) [ALR] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND byte with accumulator, then shift right one bit in accumu-lator. Status flags: N,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Immediate |ASR #arg |$4B| 2 | 2 ATX (LXA) [OAL] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND byte with accumulator, then transfer accumulator to X register. Status flags: N,Z Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Immediate |ATX #arg |$AB| 2 | 2 AXA (SHA) [AXA] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND X register with accumulator then AND result with 7 and store in memory. Status flags: - Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Absolute,Y |AXA arg,Y |$9F| 3 | 5 (Indirect),Y|AXA arg |$93| 2 | 6 AXS (SBX) [SAX] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND X register with accumulator and store result in X regis-ter, then subtract byte from X register (without borrow). Status flags: N,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Immediate |AXS #arg |$CB| 2 | 2 DCP (DCP) [DCM] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Subtract 1 from memory (without borrow). Status flags: C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |DCP arg |$C7| 2 | 5 Zero Page,X |DCP arg,X |$D7| 2 | 6 Absolute |DCP arg |$CF| 3 | 6 Absolute,X |DCP arg,X |$DF| 3 | 7 Absolute,Y |DCP arg,Y |$DB| 3 | 7 (Indirect,X)|DCP (arg,X)|$C3| 2 | 8 (Indirect),Y|DCP (arg),Y|$D3| 2 | 8 DOP (NOP) [SKB] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D No operation (double NOP). The argument has no signifi-cance. Status flags: - Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |DOP arg |$04| 2 | 3 Zero Page,X |DOP arg,X |$14| 2 | 4 Zero Page,X |DOP arg,X |$34| 2 | 4 Zero Page |DOP arg |$44| 2 | 3 Zero Page,X |DOP arg,X |$54| 2 | 4 Zero Page |DOP arg |$64| 2 | 3 Zero Page,X |DOP arg,X |$74| 2 | 4 Immediate |DOP #arg |$80| 2 | 2 Immediate |DOP #arg |$82| 2 | 2 Immediate |DOP #arg |$89| 2 | 2 Immediate |DOP #arg |$C2| 2 | 2 Zero Page,X |DOP arg,X |$D4| 2 | 4 Immediate |DOP #arg |$E2| 2 | 2 Zero Page,X |DOP arg,X |$F4| 2 | 4 ISC (ISB) [INS] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Increase memory by one, then subtract memory from accu-mulator (with borrow). Status flags: N,V,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |ISC arg |$E7| 2 | 5 Zero Page,X |ISC arg,X |$F7| 2 | 6 Absolute |ISC arg |$EF| 3 | 6 Absolute,X |ISC arg,X |$FF| 3 | 7 Absolute,Y |ISC arg,Y |$FB| 3 | 7 (Indirect,X)|ISC (arg,X)|$E3| 2 | 8 (Indirect),Y|ISC (arg),Y|$F3| 2 | 8 KIL (JAM) [HLT] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Stop program counter (processor lock up). Status flags: - Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Implied |KIL |$02| 1 | - Implied |KIL |$12| 1 | - Implied |KIL |$22| 1 | - Implied |KIL |$32| 1 | - Implied |KIL |$42| 1 | - Implied |KIL |$52| 1 | - Implied |KIL |$62| 1 | - Implied |KIL |$72| 1 | - Implied |KIL |$92| 1 | - Implied |KIL |$B2| 1 | - Implied |KIL |$D2| 1 | - Implied |KIL |$F2| 1 | - LAR (LAE) [LAS] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND memory with stack pointer, transfer result to accu-mulator, X register and stack pointer. Status flags: N,Z Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Absolute,Y |LAR arg,Y |$BB| 3 | 4 * LAX (LAX) [LAX] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Load accumulator and X register with memory. Status flags: N,Z Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |LAX arg |$A7| 2 | 3 Zero Page,Y |LAX arg,Y |$B7| 2 | 4 Absolute |LAX arg |$AF| 3 | 4 Absolute,Y |LAX arg,Y |$BF| 3 | 4 * (Indirect,X)|LAX (arg,X)|$A3| 2 | 6 (Indirect),Y|LAX (arg),Y|$B3| 2 | 5 * NOP (NOP) [NOP] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D No operation Status flags: - Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Implied |NOP |$1A| 1 | 2 Implied |NOP |$3A| 1 | 2 Implied |NOP |$5A| 1 | 2 Implied |NOP |$7A| 1 | 2 Implied |NOP |$DA| 1 | 2 Implied |NOP |$FA| 1 | 2 RLA (RLA) [RLA] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Rotate one bit left in memory, then AND accumulator with memory. Status flags: N,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |RLA arg |$27| 2 | 5 Zero Page,X |RLA arg,X |$37| 2 | 6 Absolute |RLA arg |$2F| 3 | 6 Absolute,X |RLA arg,X |$3F| 3 | 7 Absolute,Y |RLA arg,Y |$3B| 3 | 7 (Indirect,X)|RLA (arg,X)|$23| 2 | 8 (Indirect),Y|RLA (arg),Y|$33| 2 | 8 RRA (RRA) [RRA] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Rotate one bit right in memory, then add memory to accumulator (with carry). Status flags: N,V,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |RRA arg |$67| 2 | 5 Zero Page,X |RRA arg,X |$77| 2 | 6 Absolute |RRA arg |$6F| 3 | 6 Absolute,X |RRA arg,X |$7F| 3 | 7 Absolute,Y |RRA arg,Y |$7B| 3 | 7 (Indirect,X)|RRA (arg,X)|$63| 2 | 8 (Indirect),Y|RRA (arg),Y|$73| 2 | 8 SBC (SBC) [SBC] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D The same as the legal opcode $E9 (SBC #byte) Status flags: N,V,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Immediate |SBC #byte |$EB| 2 | 2 SLO (SLO) [ASO] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Shift left one bit in memory, then OR accumulator with memory. = Status flags: N,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |SLO arg |$07| 2 | 5 Zero Page,X |SLO arg,X |$17| 2 | 6 Absolute |SLO arg |$0F| 3 | 6 Absolute,X |SLO arg,X |$1F| 3 | 7 Absolute,Y |SLO arg,Y |$1B| 3 | 7 (Indirect,X)|SLO (arg,X)|$03| 2 | 8 (Indirect),Y|SLO (arg),Y|$13| 2 | 8 SRE (SRE) [LSE] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Shift right one bit in memory, then EOR accumulator with memory. Status flags: N,Z,C Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Zero Page |SRE arg |$47| 2 | 5 Zero Page,X |SRE arg,X |$57| 2 | 6 Absolute |SRE arg |$4F| 3 | 6 Absolute,X |SRE arg,X |$5F| 3 | 7 Absolute,Y |SRE arg,Y |$5B| 3 | 7 (Indirect,X)|SRE (arg,X)|$43| 2 | 8 (Indirect),Y|SRE (arg),Y|$53| 2 | 8 SXA (SHX) [XAS] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND X register with the high byte of the target address of the argument + 1. Store the result in memory. M =3D X AND HIGH(arg) + 1 Status flags: - Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Absolute,Y |SXA arg,Y |$9E| 3 | 5 SYA (SHY) [SAY] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND Y register with the high byte of the target address of the argument + 1. Store the result in memory. M =3D Y AND HIGH(arg) + 1 Status flags: - Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Absolute,X |SYA arg,X |$9C| 3 | 5 TOP (NOP) [SKW] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D No operation (tripple NOP). The argument has no signifi-cance. Status flags: - Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Absolute |TOP arg |$0C| 3 | 4 Absolute,X |TOP arg,X |$1C| 3 | 4 * Absolute,X |TOP arg,X |$3C| 3 | 4 * Absolute,X |TOP arg,X |$5C| 3 | 4 * Absolute,X |TOP arg,X |$7C| 3 | 4 * Absolute,X |TOP arg,X |$DC| 3 | 4 * Absolute,X |TOP arg,X |$FC| 3 | 4 * XAA (ANE) [XAA] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Exact operation unknown. Read the referenced documents for more information and observations. Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Immediate |XAA #arg |$8B| 2 | 2 XAS (SHS) [TAS] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D AND X register with accumulator and store result in stack pointer, then AND stack pointer with the high byte of the target address of the argument + 1. Store result in memory. S =3D X AND A, M =3D S AND HIGH(arg) + 1 Status flags: - Addressing |Mnemonics |Opc|Sz | n ------------|-----------|---|---|--- Absolute,Y |XAS arg,Y |$9B| 3 | 5