Ver el código de 6502 Códigos opcionales no documentados

Basado en el Atari 8-bit 6502C (CO14806) 
Versión 3.1, 28/6/1999 Por Freddy Offenga

Esta versión es una continuación directa de la lista de códigos opcionales no documentados (opcodes ilegales) de Joakim Atterhal (WosFilm) y mía que se publicó en la revista de discos de 8 bits de Atari llamada **Mega Magazine** ((https://archive.org/details/a8b_mega_mag_006_a número 6)). La mayoría de los opcode en esta lista se originó a partir de un desensamblador para el Atari (The Symbolic Disassembler por HiasSoft).

{{toc numerate=1}}

===La CPU Atari de 8 bits===

De hecho hay dos versiones personalizadas del 6502 para el Atari. El 6502 personalizado **CO14377** es el primero que probablemente sólo se utiliza en algunos de los primeros Atari 400/800. La 6502C personalizada **CO14806** se utiliza en todos los modelos Atari de 8 bits (400/800/XL/XE y XEGS).

===Créditos===

  * Joakim Atterhal
  * Adam Vardy
  * Craig Taylor

===Referencias===

  1. Illegal opcodes, WosFilm y Frankenstein, Mega Magazine nº 2, diciembre de 1991.
  1. Illegal opcodes v2, WosFilm y Frankenstein, Mega Magazine nº 6, octubre de 1993.
  1. Illegal Opcodes der 65xx-CPU, Frank Leiprecht, ABBUC Sondermagazin 10, Top-Magazin Oktober 1991.
  1. Erg "nzung zu den Illegalen OP-Codes, Peter W "tzel, Top-Magazin Januar 1992.
  1. 6502 Opcodes and Quasi-Opcodes, Craig Taylor, 1992.
  1. Extra Instructions Of The 65XX Series CPU, Adam Vardy, 27 Sept. 1996.

===Cambios desde la versión 2.0===

La versión 2.0 fue comparada con dos listas basadas en Commodore 8-bit encontradas en internet. Había algunas diferencias en los nombres de los opcodes, así que incluí los otros nombres también. 

  * Los nombres entre paréntesis son los nombres tomados de la lista compilada por Craig Taylor. 
  * Los nombres entre corchetes son los tomados de la lista de Adam Vardy.
  * La antigua lista también se comparó con otras dos listas basadas en Atari 8-bit (de Frank Leiprecht y Peter W "tzel).  No se encontró nada nuevo en estas listas.
  * Los valores de tiempo (ciclos de reloj) de todos los opcodes fueron comparados con los valores de la lista de Adam Vardy. No hubo diferencias.
  * Los modos de direccionamiento para las instrucciones "DOP" (double nop) y "TOP" se copiaron de la lista de Craig Taylor. La razón es que los diferentes modos de direccionamiento explican las diferencias en los valores de temporización.
  * Se eliminó el opcode $8B de la tabla "AAX". El comportamiento de este opcode parece ser comlex (como señalaron varias personas).
  * Tal vez haya más información en la próxima versión de este documento. Por ahora este opcode se llama "XAA".
  * El modo de direccionamiento para el opcode $A3 (LAX) era falso en la lista anterior. Se ha cambiado a (indirecto,x).
  * Los modos de direccionamiento para los opcodes $13 y $03 (SLO) estaban cambiados. Corregido en esta versión.
  * El modo de direccionamiento para el opcode $B7 (LAX) era "página-cero,x", pero debería ser "página-cero,y". Corregido.
  * Cambiado el sospechoso opcode $93. Este se llamaba "DOP", pero en realidad es otra instrucción "AXA".
  * Probado el comportamiento de $9E (SXA), $9C (SYA) y $9B (XAS).
  * Allí el AND estático con 7 mencionado en la lista antigua era falso.
  * La observación de la función "AND con el byte alto del argumento + 1" (de la lista de Adam Vardy) parece ser correcta.

===Códigos opcionales===

En la versión 2.1 se añade una sección sobre las dos CPU's Atari personalizadas 'quizás diferentes'. Se necesita más información :

**Opc :** Opcode en hexadecimal.
**Sz :** Tamaño en bytes.
**n :** Número de ciclos de reloj.
* **:** Añade un ciclo cuando se cruza el límite de página.

====AAC (ANC) [ANC]====

AND byte con acumulador. Si el resultado es negativo, se establece el acarreo. 
Banderas de estado: N,Z,C.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Inmediato|AAC #arg|$0B|2|2||
||Inmediato|AAC #arg|$2B|2|2||
|#

====AAX (SAX) [AXS]====

Registro AND X con acumulador y almacenamiento del resultado en memoria.
Banderas de estado: N,Z

#|
*|Direccionamiento|Mnemónicos |Opc|Sz | n|*
||Página cero|AAX arg|$87| 2|3||
||Página cero,Y|AAX arg,Y|$97|2|4||
||(Indirecto,X)|AAX (arg,X)|$83|2|6||
||Absoluto|AAX arg|$8F|3|4||
|#

====ARR (ARR) [ARR]====

AND byte con acumulador, luego girar un bit a la derecha en acumulador y comprobar bit 5 y 6:
Si ambos bits son 1: fija C, borra V.
Si ambos bits son 0: borra C y V.
Si sólo el bit 5 es 1: activa V, desactiva C.
Si sólo el bit 6 es 1: poner C y V.
Banderas de estado: N,V,Z,C.

#|
*|Direccionamiento |Mnemónicos |Opc|Sz | n|*
||Inmediato|ARR #arg |$6B|2|2||
|#

====ASR (ASR) [ALR]====

AND byte con acumulador, luego desplazar un bit a la derecha en el acumulador. 
Banderas de estado: N,Z,C.

#|
*|Direccionamiento |Mnemónicos |Opc|Sz | n|*
||Inmediato|ASR #arg|$4B|2|2||
|#

====ATX (LXA) [OAL]====

AND byte con acumulador, luego transfiere el acumulador al registro X. 
Banderas de estado: N,Z.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Inmediato|ATX #arg|$AB|2|2||
|#

====AXA (SHA) [AXA]====

AND registro X con acumulador luego AND resultado con 7 y almacenar en memoria. 
Banderas de estado: -

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Absoluto,Y|AXA arg,Y|$9F|3|5||
||(Indirecto),Y|AXA arg|$93|2|6||
|#

====AXS (SBX) [SAX]====

Suma el registro X con el acumulador y almacena el resultado en el registro X, luego resta el byte del registro X (sin préstamo).
Banderas de estado: N,Z,C

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Inmediato|AXS #arg|$CB|2|2||
|#

====DCP (DCP) [DCM]====

Resta 1 de la memoria (sin préstamo).
Banderas de estado: C.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Página cero|DCP arg|$C7|2|5||
||Página cero,X|DCP arg,X|$D7|2|6||
||Absoluto |DCP arg |$CF|3|6||
||Absoluto,X|DCP arg,X|$DF|3|7||
||Absoluto,Y|DCP arg,Y|$DB|3|7||
||(Indirecto,X)|DCP (arg,X)|$C3|2|8||
||(Indirecto),Y|DCP (arg),Y|$D3|2|8||
|#

====DOP (NOP) [SKB]====

Ninguna operación (doble NOP). El argumento no tiene significado.
Banderas de estado: -

#|
*|Direccionamiento |Mnemónicos |Opc|Sz|n|*
||Página cero |DOP arg |$04| 2 | 3||
||Página cero,X |DOP arg,X |$14| 2 | 4||
||Página cero,X |DOP arg,X |$34| 2 | 4||
||Página cero |DOP arg |$44| 2 | 3||
||Página cero,X |DOP arg,X |54$| 2 | 4||
||Página cero |DOP arg |$64| 2 | 3||
||Página cero,X |DOP arg,X |$74| 2 | 4||
||Inmediato |DOP #arg |$80| 2 | 2||
||Inmediato |DOP #arg |$82| 2 | 2||
||Inmediato |DOP #arg |$89| 2 | 2||
||Inmediato |DOP #arg |$C2| 2 | 2||
||Página cero,X |DOP arg,X |$D4| 2 | 4||
||Inmediato |DOP #arg |$E2| 2 | 2||
||Página cero,X |DOP arg,X |$F4| 2 | 4||
|#

====ISC (ISB) [INS]====

Aumenta la memoria en uno, luego resta memoria del acumulador (con préstamo). 
Banderas de estado: N,V,Z,C.

#|
*|Direccionamiento |Mnemónicos |Opc|Sz | n|*
||Página cero |ISC arg |$E7| 2 | 5||
||Página cero,X |ISC arg,X |$F7| 2 | 6||
||Absoluto |ISC arg |$EF| 3 | 6||
||Absoluto,X |ISC arg,X |$FF| 3 | 7||
||Absoluto,Y |ISC arg,Y |$FB| 3 | 7||
||(Indirecto,X)|ISC (arg,X)|$E3| 2 | 8||
||(Indirecto),Y|ISC (arg),Y|$F3| 2 | 8||
|#

====KIL (JAM) [HLT]====

Parada del contador de programa (bloqueo del procesador).
Banderas de estado: -

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Implícito|KIL|$02|1|-||
||Implícito|KIL|$12|1|-||
||Implícito|KIL|$22|1|-||
||Implícito|KIL|$32|1|-||
||Implícito|KIL|$42|1|-||
||Implícito|KIL|$52|1|-||
||Implícito|KIL|$62|1|-||
||Implícito|KIL|$72|1|-||
||Implícito|KIL|$92|1|-||
||Implícito|KIL|$B2|1|-||
||Implícito|KIL|$D2|1|-||
||Implícito|KIL|$F2|1|-||
|#

====LAR (LAE) [LAS]====

AND memoria con puntero de pila, transfiere resultado a acumulador, registro X y puntero de pila.
Banderas de estado: N,Z.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Absoluto,Y|LAR arg,Y|$BB|3|4 *||
|#

====LAX (LAX) [LAX]====

Carga el acumulador y el registro X con memoria.
Banderas de estado: N,Z.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Página cero|LAX arg |$A7|2|3||
||Página cero,Y|LAX arg,Y|$B7|2|4||
||Absoluto|LAX arg |$AF|3|4||
||Absoluto,Y|LAX arg,Y|$BF|3|4 *||
||(Indirecto,X)|LAX (arg,X)|$A3|2|6||
||(Indirecto),Y|LAX (arg),Y|$B3|2| 5 *||
|#

====NOP (NOP) [NOP]====

Sin operación
Indicadores de estado: -

#|
*|Direccionamiento|Mnemónicos |Opc|Sz | n|*
||Implícito|NOP|$1A|1|2||
||Implícito|NOP|$3A|1|2||
||Implícito|NOP|$5A|1|2||
||Implícito|NOP|$7A|1|2||
||Implícito|NOP|$DA|1|2||
||Implícito|NOP|$FA|1|2||
|#

====RLA (RLA) [RLA]====

Gira un bit a la izquierda en memoria, luego AND acumulador con memoria. 
Banderas de estado: N,Z,C.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Página cero|RLA arg|$27|2|5||
||Página cero,X|RLA arg,X|$37|2|6||
||Absoluto|RLA arg|$2F|3|6||
||Absoluto,X|RLA arg,X|$3F|3|7||
||Absoluto,Y|RLA arg,Y|$3B|3|7||
||(Indirecto,X)|RLA (arg,X)|$23|2|8||
||(Indirecto),Y|RLA (arg),Y|$33|2|8||
|#

====RRA (RRA) [RRA]====

Gira un bit a la derecha en la memoria, luego suma la memoria al acumulador (con acarreo).
Banderas de estado: N,V,Z,C.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Página cero|RRA arg|$67|2|5||
||Página cero,X|RRA arg,X|$77|2|6||
||Absoluto|RRA arg|$6F|3|6||
||Absoluto,X|RRA arg,X|$7F|3|7||
||Absoluto,Y|RRA arg,Y|$7B|3|7||
||(Indirecto,X)|RRA (arg,X)|$63|2|8||
||(Indirecto),Y|RRA (arg),Y|$73|2|8||
|#

====SBC (SBC) [SBC]====

Igual que el opcode legal $E9 (SBC #byte)
Banderas de estado: N,V,Z,C.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Inmediato|SBC #byte|$EB|2|2||
|#

====SLO (SLO) [ASO]====

Desplazar un bit a la izquierda en memoria, luego OR acumulador con memoria.
Banderas de estado: N,Z,C.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Página cero|SLO arg |$07|2|5||
||Página cero,X |SLO arg,X |$17|2|6||
||Absoluto |SLO arg |$0F|3|6||
||Absoluto,X |SLO arg,X |$1F|3|7||
||Absoluto,Y |SLO arg,Y |$1B|3|7||
||(Indirecto,X)|SLO (arg,X)|$03|2|8||
||(Indirecto),Y|SLO (arg),Y|$13|2|8||
|#

====SRE (SRE) [LSE]====

Desplazar un bit a la derecha en memoria, luego EOR acumulador con memoria. 
Banderas de estado: N,Z,C.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Página cero|SRE arg|$47|2|5||
||Página cero,X|SRE arg,X|$57|2|6||
||Absoluto|SRE arg|$4F|3|6||
||Absoluto,X|SRE arg,X|$5F|3|7||
||Absoluto,Y|SRE arg,Y|$5B|3|7||
||(Indirecto,X)|SRE (arg,X)|$43|2|8||
||(Indirecto),Y|SRE (arg),Y|$53|2|8||
|#

====SXA (SHX) [XAS]====

AND el registro X con el byte alto de la dirección destino del argumento +1. Almacenar el resultado en memoria.
M = X AND ALTO(arg) +1
Banderas de estado: -

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Absoluto,Y|SXA arg,Y|$9E|3|5||
|#

====SYA (SHY) [SAY]====

AND el registro Y con el byte alto de la dirección de destino del argumento +1. Almacenar el resultado en memoria.
M = Y AND ALTO(arg) + 1
Banderas de estado: -

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Absoluto,X|SYA arg,X|$9C|3|5||
|#

====TOP (NOP) [SKW]====

Ninguna operación (triple NOP). El argumento no tiene significado.
Banderas de estado: -

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Absoluto|TOP arg|$0C|3|4||
||Absoluto,X|TOP arg,X|$1C|3|4 *||
||Absoluto,X|TOP arg,X|$3C|3|4 *||
||Absoluto,X|TOP arg,X|$5C|3|4 *||
||Absoluto,X|TOP arg,X|$7C|3|4 *||
||Absoluto,X|TOP arg,X|$DC|3|4 *||
||Absoluto,X|TOP arg,X|$FC|3|4 *||
|#

====XAA (ANE) [XAA]====

Operación exacta desconocida. Lea los documentos referenciados para más información y observaciones.

#|
*|Direccionamiento|Mnemónicos|Opc|Sz|n|*
||Inmediato|XAA #arg|$8B|2|2||
|#

====XAS (SHS) [TAS]====

AND el registro X con el acumulador y almacena el resultado en el puntero de pila, luego AND el puntero de pila con el byte alto de la dirección de destino del argumento + 1. Almacena el resultado en memoria. Almacenar el resultado en memoria.
S = X AND A, M = S AND HIGH(arg) + 1
Banderas de estado: -

#|
*|Direccionamiento |Mnemónicos|Opc|Sz|n|*
||Absoluto,Y|XAS arg,Y|$9B|3|5||
|#