

                                 ACME

         ...the ACME Crossassembler for Multiple Environments

               --- Undocumented ("illegal") opcodes ---


In release 0.87, support for some of the undocumented opcodes of the
NMOS 6502 processor was added.
In release 0.89, some more were added.
In release 0.94.8, another one ("LXA") was added.
In release 0.95.2, the "ANC" opcode was changed from 0x2b to 0x0b.
In release 0.95.3, C64DTV2 support was added, which includes these
opcodes as well.
In release 0.95.4, the remaining seven were added.
In release 0.95.6, "ANC" was removed from C64DTV2 mode.

Here are the new mnemonics, possible addressing modes and generated
opcodes (mnemonics in parentheses are used by other sources):

                |           addressing  mode           |
 mnemonic       |  8  8,x 8,y 16 16,x 16,y (8,x) (8),y | performs:
----------------+--------------------------------------+-----------
 slo (aso)      | 07  17      0f  1f   1b   03    13   | asl + ora
 rla (rln)      | 27  37      2f  3f   3b   23    33   | rol + and
 sre (lse)      | 47  57      4f  5f   5b   43    53   | lsr + eor
 rra (rrd)      | 67  77      6f  7f   7b   63    73   | ror + adc
 sax (axs, aax) | 87      97  8f            83         | stx + sta
 lax            | a7      b7  af       bf   a3    b3   | ldx + lda
 dcp (dcm)      | c7  d7      cf  df   db   c3    d3   | dec + cmp
 isc (isb, ins) | e7  f7      ef  ff   fb   e3    f3   | inc + sbc
 las (lar, lae) |                      bb              | A,X,S = {addr} & S
 tas (shs, xas) |                      9b              | S = A & X    {addr} = A&X& {H+1}
 sha (axa, ahx) |                      9f         93   | {addr} = A & X & {H+1}
 shx (xas, sxa) |                      9e              | {addr} = X & {H+1}
 shy (say, sya) |                 9c                   | {addr} = Y & {H+1}

                |         addressing mode         |
 mnemonic       | implied #8    8   8,x  16  16,x | performs:
----------------+---------------------------------+-----------------------
 anc (ana)      |         0b*                     | A = A & arg, then C=N
 anc (anb)      |         2b*                     | A = A & arg, then C=N
 alr/asr        |         4b                      | A = A & arg, then lsr
 arr            |         6b                      | A = A & arg, then ror
 sbx (axs, sax) |         cb                      | X = (A & X) - arg
 dop (nop, skb) |   80**  80   04   14            | skips next byte
 top (nop, skw) |   0c**                 0c   1c  | skips next two bytes
 nop (skb, skw) |   ea    80   04   14   0c   1c  | see the two lines above
 jam (kil, hlt) |   02                            | crash (wait for reset)
These two are somewhat unstable, because they involve an arbitrary value:
 ane (xaa, axm) |         8b***                   | A = (A | ??) & X & arg
 lxa (lax, atx) |         ab***                   | A,X = (A | ??) & arg

Example:
		!cpu nmos6502	; activate additional mnemonics...
		lax (some_zp_label,x)	; ...and use them. No, this
		dcp (other_zp_label),y	; example does not make sense.

*) Up until ACME version 0.95.1, anc#8 generated opcode 0x2b. Since
ACME version 0.95.2, anc#8 generates opcode 0x0b. Both opcodes work
the same way on a real NMOS 6502 CPU, but they do not work on the
C64DTV2.

**) Note that DOP ("double nop") and TOP ("triple nop") can be used
with implied addressing, but the generated opcodes are those for
immediate and 16-bit absolute addressing, respectively, This way DOP
and TOP can be used to skip the following one- or two-byte
instruction.
Using DOP/TOP with x-indexed addressing might have its uses when
timing is critical (crossing a page border adds a penalty cycle).
Unless using implied addressing, DOP/TOP can also be written as NOP.

***) ANE and LXA first perform an ORA with an arbitrary(!) value and
then perform an AND with the given argument. So they are unstable and
therefore useless - unless the given argument is zero:
ANE #0 reliably clears A - which is still useless; just use LDA #0.
LXA #0 reliably clears both A and X.
ACME will output a warning if these opcodes get assembled with a
nonzero argument.

There is no guarantee that these opcodes actually work on a given 6502
(or 6510, or 8500, or 8501, or 8502) CPU. But as far as I know, nobody
ever found an unmodified C64/C128 where these illegals didn't work.

These illegals will definitely *not* work on 65c02 and 65816 CPUs. But
I really should not have to tell you that ;)

Because there are no official mnemonics for these opcodes, different
people use different names for them. I hope my choices are not too
exotic for your taste.

Just for the sake of completeness: Here are all the remaining opcodes
(the ones ACME won't generate even with "nmos6502" cpu chosen):

Opcode|  Description                                          C64DTV2
------+--------------------------------------------------------------
  12  |  same as 02 and others    jam                 CRASH   bra rel
  1a  |  same as (*legal*) ea     nop
  22  |  same as 02 and others    jam                 CRASH
  2b  |  same as 0b               anc #8                      dop
  32  |  same as 02 and others    jam                 CRASH   sac #8
  34  |  same as 14 and others    dop 8,x
  3a  |  same as (*legal*) ea     nop
  3c  |  same as 1c and others    top 16,x
  42  |  same as 02 and others    jam                 CRASH   sir #8
  44  |  same as 04               dop 8
  52  |  same as 02 and others    jam                 CRASH
  54  |  same as 14 and others    dop 8,x
  5a  |  same as (*legal*) ea     nop
  5c  |  same as 1c and others    top 16,x
  62  |  same as 02 and others    jam                 CRASH
  64  |  same as 04               dop 8
  72  |  same as 02 and others    jam                 CRASH
  74  |  same as 14 and others    dop 8,x
  7a  |  same as (*legal*) ea     nop
  7c  |  same as 1c and others    top 16,x
  82  |  same as c2/e2            dop #8, but said to CRASH sometimes
  89  |  same as 80               dop #8
  92  |  same as 02 and others    jam                 CRASH
  b2  |  same as 02 and others    jam                 CRASH
  c2  |  same as 82/e2            dop #8, but said to CRASH sometimes
  d2  |  same as 02 and others    jam                 CRASH
  d4  |  same as 14 and others    dop 8,x
  da  |  same as (*legal*) ea     nop
  dc  |  same as 1c and others    top 16,x
  e2  |  same as 82/c2            dop #8, but said to CRASH sometimes
  eb  |  same as (*legal*) e9     sbc #8
  f2  |  same as 02 and others    jam                 CRASH
  f4  |  same as 14 and others    dop 8,x
  fa  |  same as (*legal*) ea     nop
  fc  |  same as 1c and others    top 16,x

For more information about what these opcodes do, see these documents:
  John West, Marko Mäkelä. '64doc' file, 1994/06/03.
  Extra Instructions Of The 65XX Series CPU, Adam Vardy, 27 Sept. 1996
  6502 Undocumented Opcodes, by Freddy Offenga, 5/17/1997
  AAY64 (All About Your 64)

...but the most comprehensive work is:

    "No More Secrets - NMOS 6510 Unintended Opcodes"

Download it from    https://csdb.dk/release/?id=248511
or ask google for the latest version.
