From e85f677cbde2aa08357c489ed3e2c22ecceb5863 Mon Sep 17 00:00:00 2001 From: marcobaye Date: Tue, 25 Nov 2014 23:57:15 +0000 Subject: [PATCH] Release 0.95.4: Added the last remaining undocumented ("illegal") opcodes: LAS, TAS, SHA, SHX, SHY and ANE. git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@44 4df02467-bbd4-4a76-a152-e7ce94205b78 --- docs/Changes.txt | 8 ++++ docs/Illegals.txt | 101 +++++++++++++++++++++------------------------- src/acme.c | 4 +- src/cpu.c | 4 +- src/cpu.h | 2 +- src/mnemo.c | 65 ++++++++++++++++------------- 6 files changed, 97 insertions(+), 87 deletions(-) diff --git a/docs/Changes.txt b/docs/Changes.txt index 82f2c71..b083225 100644 --- a/docs/Changes.txt +++ b/docs/Changes.txt @@ -12,6 +12,14 @@ platform used. There should be another help file in this archive outlining the platform specific changes. +---------------------------------------------------------------------- +Section: New in release 0.95.4 +---------------------------------------------------------------------- + +Added the last remaining undocumented ("illegal") opcodes: LAS, TAS, + SHA, SHX, SHY and ANE. + + ---------------------------------------------------------------------- Section: New in release 0.95.3 ---------------------------------------------------------------------- diff --git a/docs/Illegals.txt b/docs/Illegals.txt index fba1704..de120a9 100644 --- a/docs/Illegals.txt +++ b/docs/Illegals.txt @@ -13,32 +13,42 @@ In release 0.89, some more were added. In release 0.94.8, another one was added (lxa). 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. -Here are the mnemonics, addressing modes and generated opcodes: +Here are the new mnemonics, possible addressing modes and generated +opcodes (mnemonics in parentheses are used by other sources): - | addressing mode | -Mnemo | 8 8,x 8,y 16 16,x 16,y (8,x) (8),y | performs: -------+--------------------------------------------------+----------- - slo | 07 17 -- 0f 1f 1b 03 13 | asl + ora - rla | 27 37 -- 2f 3f 3b 23 33 | rol + and - sre | 47 57 -- 4f 5f 5b 43 53 | lsr + eor - rra | 67 77 -- 6f 7f 7b 63 73 | ror + adc - sax | 87 -- 97 8f -- -- 83 -- | stx + sta - lax | a7 -- b7 af -- bf a3 b3 | ldx + lda - dcp | c7 d7 -- cf df db c3 d3 | dec + cmp - isc | e7 f7 -- ef ff fb e3 f3 | inc + sbc + | 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 | 27 37 2f 3f 3b 23 33 | rol + and + sre (lse) | 47 57 4f 5f 5b 43 53 | lsr + eor + rra | 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 +These five are said to be unstable: + 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 | -Mnemo | implied #8 8 8,x 16 16,x | performs: -------+-------------------------------------+------------------------ - anc | -- 0b* -- -- -- -- | A = A & arg, then C=N - asr | -- 4b -- -- -- -- | A = A & arg, then lsr - arr | -- 6b -- -- -- -- | A = A & arg, then ror - sbx | -- cb -- -- -- -- | X = (A & X) - arg - dop | 80** 80 04 14 -- -- | skips next byte - top | 0c** -- -- -- 0c 1c | skips next two bytes - jam | 02 -- -- -- -- -- | crash (wait for reset) - lxa | -- ab*** -- -- -- -- | A/X = (A | ??) & arg + | addressing mode | + mnemonic | implied #8 8 8,x 16 16,x | performs: +----------------+---------------------------------+----------------------- + anc | 0b* | A = A & arg, then C=N + asr (alr) | 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 + jam (kil, hlt) | 02 | crash (wait for reset) +These two are somewhat unstable, because they involve an arbitrary value: + ane (xaa) | 8b*** | A = (A | ??) & X & arg + lxa (lax, atx) | ab*** | A,X = (A | ??) & arg Example: !cpu 6510 ; activate additional mnemonics... @@ -49,16 +59,19 @@ Example: ACME version 0.95.2, anc#8 generates opcode 0x0b. Both opcodes work the same way on a 6510. I am told 0x2b does not work on the C64DTV2. -**) Note that "dop" and "top" can be used with implied addressing, but -the generated opcodes are those for immediate and 16-bit absolute -addressing, respectively. Using dop/top with x-indexed addressing -might have its uses when timing is critical (crossing a page border -adds a penalty cycle). +**) 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. Using dop/top +with x-indexed addressing might have its uses when timing is critical +(crossing a page border adds a penalty cycle). -***) This opcode is said to first perform an ORA with an arbitrary(!) -value, then do an AND with the given argument, then do a TAX. -This means it is unstable and therefore useless - unless the given -argument is zero, in which case it reliably clears both A and X. +***) 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 8502) CPU. But as far as I know, nobody ever @@ -100,15 +113,8 @@ Opcode| Description C64DTV2 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 - 8b | see notes below 92 | same as 02 and others jam CRASH - 93 | see notes below - 9b | see notes below - 9c | see notes below - 9e | see notes below - 9f | see notes below b2 | same as 02 and others jam CRASH - bb | see notes below 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 @@ -121,22 +127,9 @@ Opcode| Description C64DTV2 fa | same as (*legal*) ea nop fc | same as 1c and others top 16,x - -Concerning opcodes 8b, 93, 9b, 9c, 9e, 9f, bb: - -These opcodes are said to be unstable. For more information about what -they do, see these documents: +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) - -I did not see much point in assigning mnemonics for these opcodes. The -reference documents above call them: - 8b: ane, xaa - 93: sha, axa, ahx - 9b: shs, tas, xas - 9c: shy, say, sya - 9e: shx, xas, sxa - 9f: sha, axa, ahx - bb: las, lar, lae + NMOS 6510 Unintended Opcodes diff --git a/src/acme.c b/src/acme.c index da8862f..bfc4d73 100644 --- a/src/acme.c +++ b/src/acme.c @@ -15,9 +15,9 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#define RELEASE "0.95.3" // update before release (FIXME) +#define RELEASE "0.95.4" // update before release (FIXME) #define CODENAME "Fenchurch" // update before release -#define CHANGE_DATE "25 Nov" // update before release +#define CHANGE_DATE "26 Nov" // update before release #define CHANGE_YEAR "2014" // update before release //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME diff --git a/src/cpu.c b/src/cpu.c index ca9af44..d854e63 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -23,13 +23,13 @@ static struct cpu_type cpu_type_6502 = { static struct cpu_type cpu_type_6510 = { keyword_is_6510mnemo, CPUFLAG_INDIRECTJMPBUGGY | // JMP ($xxFF) is buggy - CPUFLAG_AB_NEEDS_0_ARG, // LXA #$xx is unstable unless arg is $00 + CPUFLAG_8B_AND_AB_NEED_0_ARG, // ANE/LXA #$xx are unstable unless arg is $00 234 // !align fills with "NOP" }; static struct cpu_type cpu_type_c64dtv2 = { keyword_is_c64dtv2mnemo, CPUFLAG_INDIRECTJMPBUGGY | // JMP ($xxFF) is buggy - CPUFLAG_AB_NEEDS_0_ARG, // LXA #$xx is unstable unless arg is $00 (FIXME - correct?) + CPUFLAG_8B_AND_AB_NEED_0_ARG, // ANE/LXA #$xx are unstable unless arg is $00 (FIXME - correct?) 234 // !align fills with "NOP" }; static struct cpu_type cpu_type_65c02 = { diff --git a/src/cpu.h b/src/cpu.h index a3ecabf..028600a 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -20,7 +20,7 @@ struct cpu_type { }; #define CPUFLAG_INDIRECTJMPBUGGY (1u << 0) // warn if "jmp ($xxff)" is assembled #define CPUFLAG_SUPPORTSLONGREGS (1u << 1) // allow "!al" and "!rl" pseudo opcodes -#define CPUFLAG_AB_NEEDS_0_ARG (1u << 2) // warn if "lxa #$xx" uses non-zero arg +#define CPUFLAG_8B_AND_AB_NEED_0_ARG (1u << 2) // warn if "ane/lxa #$xx" uses non-zero arg // create cpu type tree (is done early) extern void CPUtype_init(void); diff --git a/src/mnemo.c b/src/mnemo.c index e3d020d..78db8b4 100644 --- a/src/mnemo.c +++ b/src/mnemo.c @@ -89,19 +89,19 @@ enum mnemogroup { // column to use here. The row depends on the used addressing mode. A zero // entry in these tables means that the combination of mnemonic and addressing // mode is illegal. -// | 6502 | 65c02 | 65816 | 6510 illegals | -enum { IDX_ORA,IDX_AND,IDX_EOR,IDX_ADC,IDX_STA,IDX_LDA,IDX_CMP,IDX_SBC,IDXcORA,IDXcAND,IDXcEOR,IDXcADC,IDXcSTA,IDXcLDA,IDXcCMP,IDXcSBC,IDX816ORA,IDX816AND,IDX816EOR,IDX816ADC,IDX816STA,IDX816LDA,IDX816CMP,IDX816SBC,IDX816PEI,IDX_SLO,IDX_RLA,IDX_SRE,IDX_RRA,IDX_SAX,IDX_LAX,IDX_DCP,IDX_ISC}; -SCL accu_abs[] = { 0x0d05, 0x2d25, 0x4d45, 0x6d65, 0x8d85, 0xada5, 0xcdc5, 0xede5, 0x0d05, 0x2d25, 0x4d45, 0x6d65, 0x8d85, 0xada5, 0xcdc5, 0xede5, 0x0f0d05, 0x2f2d25, 0x4f4d45, 0x6f6d65, 0x8f8d85, 0xafada5, 0xcfcdc5, 0xefede5, 0, 0x0f07, 0x2f27, 0x4f47, 0x6f67, 0x8f87, 0xafa7, 0xcfc7, 0xefe7}; // $ff $ffff $ffffff -SCL accu_xabs[] = { 0x1d15, 0x3d35, 0x5d55, 0x7d75, 0x9d95, 0xbdb5, 0xddd5, 0xfdf5, 0x1d15, 0x3d35, 0x5d55, 0x7d75, 0x9d95, 0xbdb5, 0xddd5, 0xfdf5, 0x1f1d15, 0x3f3d35, 0x5f5d55, 0x7f7d75, 0x9f9d95, 0xbfbdb5, 0xdfddd5, 0xfffdf5, 0, 0x1f17, 0x3f37, 0x5f57, 0x7f77, 0, 0, 0xdfd7, 0xfff7}; // $ff,x $ffff,x $ffffff,x -SCS accu_yabs[] = { 0x1900, 0x3900, 0x5900, 0x7900, 0x9900, 0xb900, 0xd900, 0xf900, 0x1900, 0x3900, 0x5900, 0x7900, 0x9900, 0xb900, 0xd900, 0xf900, 0x1900, 0x3900, 0x5900, 0x7900, 0x9900, 0xb900, 0xd900, 0xf900, 0, 0x1b00, 0x3b00, 0x5b00, 0x7b00, 0x97, 0xbfb7, 0xdb00, 0xfb00}; // $ff,y $ffff,y -SCB accu_xind8[] = { 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0, 0x03, 0x23, 0x43, 0x63, 0x83, 0xa3, 0xc3, 0xe3}; // ($ff,x) -SCB accu_indy8[] = { 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0, 0x13, 0x33, 0x53, 0x73, 0, 0xb3, 0xd3, 0xf3}; // ($ff),y -SCB accu_imm[] = { 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // #$ff #$ffff -SCB accu_ind8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0x12, 0x32, 0x52, 0x72, 0x92, 0xb2, 0xd2, 0xf2, 0x12, 0x32, 0x52, 0x72, 0x92, 0xb2, 0xd2, 0xf2, 0xd4, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff) -SCB accu_sabs8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x03, 0x23, 0x43, 0x63, 0x83, 0xa3, 0xc3, 0xe3, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff,s -SCB accu_sindy8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x13, 0x33, 0x53, 0x73, 0x93, 0xb3, 0xd3, 0xf3, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff,s),y -SCB accu_lind8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x07, 0x27, 0x47, 0x67, 0x87, 0xa7, 0xc7, 0xe7, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff] -SCB accu_lindy8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x17, 0x37, 0x57, 0x77, 0x97, 0xb7, 0xd7, 0xf7, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff],y +// | 6502 | 65c02 | 65816 | 6510 illegals | +enum { IDX_ORA,IDX_AND,IDX_EOR,IDX_ADC,IDX_STA,IDX_LDA,IDX_CMP,IDX_SBC,IDXcORA,IDXcAND,IDXcEOR,IDXcADC,IDXcSTA,IDXcLDA,IDXcCMP,IDXcSBC,IDX816ORA,IDX816AND,IDX816EOR,IDX816ADC,IDX816STA,IDX816LDA,IDX816CMP,IDX816SBC,IDX816PEI,IDX_SLO,IDX_RLA,IDX_SRE,IDX_RRA,IDX_SAX,IDX_LAX,IDX_DCP,IDX_ISC,IDX_SHA}; +SCL accu_abs[] = { 0x0d05, 0x2d25, 0x4d45, 0x6d65, 0x8d85, 0xada5, 0xcdc5, 0xede5, 0x0d05, 0x2d25, 0x4d45, 0x6d65, 0x8d85, 0xada5, 0xcdc5, 0xede5, 0x0f0d05, 0x2f2d25, 0x4f4d45, 0x6f6d65, 0x8f8d85, 0xafada5, 0xcfcdc5, 0xefede5, 0, 0x0f07, 0x2f27, 0x4f47, 0x6f67, 0x8f87, 0xafa7, 0xcfc7, 0xefe7, 0}; // $ff $ffff $ffffff +SCL accu_xabs[] = { 0x1d15, 0x3d35, 0x5d55, 0x7d75, 0x9d95, 0xbdb5, 0xddd5, 0xfdf5, 0x1d15, 0x3d35, 0x5d55, 0x7d75, 0x9d95, 0xbdb5, 0xddd5, 0xfdf5, 0x1f1d15, 0x3f3d35, 0x5f5d55, 0x7f7d75, 0x9f9d95, 0xbfbdb5, 0xdfddd5, 0xfffdf5, 0, 0x1f17, 0x3f37, 0x5f57, 0x7f77, 0, 0, 0xdfd7, 0xfff7, 0}; // $ff,x $ffff,x $ffffff,x +SCS accu_yabs[] = { 0x1900, 0x3900, 0x5900, 0x7900, 0x9900, 0xb900, 0xd900, 0xf900, 0x1900, 0x3900, 0x5900, 0x7900, 0x9900, 0xb900, 0xd900, 0xf900, 0x1900, 0x3900, 0x5900, 0x7900, 0x9900, 0xb900, 0xd900, 0xf900, 0, 0x1b00, 0x3b00, 0x5b00, 0x7b00, 0x97, 0xbfb7, 0xdb00, 0xfb00, 0x9f00}; // $ff,y $ffff,y +SCB accu_xind8[] = { 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0, 0x03, 0x23, 0x43, 0x63, 0x83, 0xa3, 0xc3, 0xe3, 0}; // ($ff,x) +SCB accu_indy8[] = { 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0, 0x13, 0x33, 0x53, 0x73, 0, 0xb3, 0xd3, 0xf3, 0x93}; // ($ff),y +SCB accu_imm[] = { 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // #$ff #$ffff +SCB accu_ind8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0x12, 0x32, 0x52, 0x72, 0x92, 0xb2, 0xd2, 0xf2, 0x12, 0x32, 0x52, 0x72, 0x92, 0xb2, 0xd2, 0xf2, 0xd4, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff) +SCB accu_sabs8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x03, 0x23, 0x43, 0x63, 0x83, 0xa3, 0xc3, 0xe3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff,s +SCB accu_sindy8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x13, 0x33, 0x53, 0x73, 0x93, 0xb3, 0xd3, 0xf3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff,s),y +SCB accu_lind8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x07, 0x27, 0x47, 0x67, 0x87, 0xa7, 0xc7, 0xe7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff] +SCB accu_lindy8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x17, 0x37, 0x57, 0x77, 0x97, 0xb7, 0xd7, 0xf7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff],y // Code tables for group GROUP_MISC: // These tables are needed for finding out the correct code in cases when @@ -109,13 +109,13 @@ SCB accu_lindy8[] = { 0, 0, 0, 0, 0, 0, 0, // mnemotable), the assembler finds out the column to use here. The row // depends on the used addressing mode. A zero entry in these tables means // that the combination of mnemonic and addressing mode is illegal. -// | 6502 | 65c02 | 65816 | 6510 illegals | C64DTV2 | -enum { IDX_BIT,IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_STY,IDX_STX,IDX_LDY,IDX_LDX,IDX_CPY,IDX_CPX,IDX_DEC,IDX_INC,IDXcTSB,IDXcTRB,IDXcBIT,IDXcDEC,IDXcINC,IDXcSTZ,IDX816COP,IDX816REP,IDX816SEP,IDX816PEA,IDX_ANC,IDX_ASR,IDX_ARR,IDX_SBX,IDX_DOP,IDX_TOP,IDX_JAM,IDX_LXA,IDX_SAC,IDX_SIR}; -SCS misc_abs[] = { 0x2c24, 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0x8c84, 0x8e86, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0xcec6, 0xeee6, 0x0c04, 0x1c14, 0x2c24, 0xcec6, 0xeee6, 0x9c64, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x04, 0x0c00, 0, 0, 0, 0}; // $ff $ffff -SCS misc_xabs[] = { 0, 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0x94, 0, 0xbcb4, 0, 0, 0, 0xded6, 0xfef6, 0, 0, 0x3c34, 0xded6, 0xfef6, 0x9e74, 0, 0, 0, 0, 0, 0, 0, 0, 0x14, 0x1c00, 0, 0, 0, 0}; // $ff,x $ffff,x -SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0, 0x96, 0, 0xbeb6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff,y $ffff,y -SCB misc_imm[] = { 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0, 0, 0, 0x89, 0, 0, 0, 0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0, 0, 0xab, 0x32, 0x42}; // #$ff -SCB misc_impl[] = { 0, 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0x1a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0c, 0x02, 0, 0, 0}; // implied/accu +// | 6502 | 65c02 | 65816 | 6510 illegals | C64DTV2 | +enum { IDX_BIT,IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_STY,IDX_STX,IDX_LDY,IDX_LDX,IDX_CPY,IDX_CPX,IDX_DEC,IDX_INC,IDXcTSB,IDXcTRB,IDXcBIT,IDXcDEC,IDXcINC,IDXcSTZ,IDX816COP,IDX816REP,IDX816SEP,IDX816PEA,IDX_ANC,IDX_ASR,IDX_ARR,IDX_SBX,IDX_DOP,IDX_TOP,IDX_JAM,IDX_LXA,IDX_ANE,IDX_LAS,IDX_TAS,IDX_SHX,IDX_SHY,IDX_SAC,IDX_SIR}; +SCS misc_abs[] = { 0x2c24, 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0x8c84, 0x8e86, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0xcec6, 0xeee6, 0x0c04, 0x1c14, 0x2c24, 0xcec6, 0xeee6, 0x9c64, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x04, 0x0c00, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff $ffff +SCS misc_xabs[] = { 0, 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0x94, 0, 0xbcb4, 0, 0, 0, 0xded6, 0xfef6, 0, 0, 0x3c34, 0xded6, 0xfef6, 0x9e74, 0, 0, 0, 0, 0, 0, 0, 0, 0x14, 0x1c00, 0, 0, 0, 0, 0, 0, 0x9c00, 0, 0}; // $ff,x $ffff,x +SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0, 0x96, 0, 0xbeb6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xbb00, 0x9b00, 0x9e00, 0, 0, 0}; // $ff,y $ffff,y +SCB misc_imm[] = { 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0, 0, 0, 0x89, 0, 0, 0, 0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0, 0, 0xab, 0x8b, 0, 0, 0, 0, 0x32, 0x42}; // #$ff +SCB misc_impl[] = { 0, 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0x1a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0c, 0x02, 0, 0, 0, 0, 0, 0, 0, 0}; // implied/accu // Code tables for group GROUP_ALLJUMPS: // These tables are needed for finding out the correct code when the mnemonic @@ -227,18 +227,24 @@ static struct ronode mnemos_6510[] = { PREDEFNODE("rla", MERGE(GROUP_ACCU, IDX_RLA)), // ROL + AND PREDEFNODE("sre", MERGE(GROUP_ACCU, IDX_SRE)), // LSR + EOR (aka LSE) PREDEFNODE("rra", MERGE(GROUP_ACCU, IDX_RRA)), // ROR + ADC - PREDEFNODE("sax", MERGE(GROUP_ACCU, IDX_SAX)), // STX + STA (aka AAX aka AXS) + PREDEFNODE("sax", MERGE(GROUP_ACCU, IDX_SAX)), // STX + STA (aka AXS aka AAX) PREDEFNODE("lax", MERGE(GROUP_ACCU, IDX_LAX)), // LDX + LDA PREDEFNODE("dcp", MERGE(GROUP_ACCU, IDX_DCP)), // DEC + CMP (aka DCM) PREDEFNODE("isc", MERGE(GROUP_ACCU, IDX_ISC)), // INC + SBC (aka ISB aka INS) + PREDEFNODE("las", MERGE(GROUP_MISC, IDX_LAS)), // A,X,S = {addr} & S (aka LAR aka LAE) + PREDEFNODE("tas", MERGE(GROUP_MISC, IDX_TAS)), // S = A & X {addr} = A&X& {H+1} (aka SHS aka XAS) + PREDEFNODE("sha", MERGE(GROUP_ACCU, IDX_SHA)), // {addr} = A & X & {H+1} (aka AXA aka AHX) + PREDEFNODE("shx", MERGE(GROUP_MISC, IDX_SHX)), // {addr} = X & {H+1} (aka XAS aka SXA) + PREDEFNODE("shy", MERGE(GROUP_MISC, IDX_SHY)), // {addr} = Y & {H+1} (aka SAY aka SYA) PREDEFNODE("anc", MERGE(GROUP_MISC, IDX_ANC)), // ROL + AND, ASL + ORA (aka AAC) PREDEFNODE(s_asr, MERGE(GROUP_MISC, IDX_ASR)), // LSR + EOR (aka ALR) PREDEFNODE("arr", MERGE(GROUP_MISC, IDX_ARR)), // ROR + ADC PREDEFNODE("sbx", MERGE(GROUP_MISC, IDX_SBX)), // DEX + CMP (aka AXS aka SAX) PREDEFNODE("dop", MERGE(GROUP_MISC, IDX_DOP)), // skip next byte - PREDEFNODE("top", MERGE(GROUP_MISC, IDX_TOP)), // skip next two bytes + PREDEFNODE("top", MERGE(GROUP_MISC, IDX_TOP)), // skip next word PREDEFNODE("jam", MERGE(GROUP_MISC, IDX_JAM)), // jam/crash/kill/halt-and-catch-fire - PREDEFLAST("lxa", MERGE(GROUP_MISC, IDX_LXA)), // ORA #?? + AND #arg + TAX (aka OAL aka ATX) + PREDEFNODE("ane", MERGE(GROUP_MISC, IDX_ANE)), // A = (A | ??) & X & arg (aka XAA) + PREDEFLAST("lxa", MERGE(GROUP_MISC, IDX_LXA)), // A,X = (A | ??) & arg (aka OAL aka ATX) // ^^^^ this marks the last element }; @@ -768,12 +774,15 @@ static void group_misc(int index, int imm_flag) // CAUTION - do not incorporate the line above into the line // below - "force_bit" might be undefined (depends on compiler). make_command(force_bit, &result, imm_opcodes); - // check whether to warn about 6510's unstable LXA - if ((imm_opcodes == 0xab) + // check whether to warn about 6510's unstable ANE/LXA + if ((CPU_state.type->flags & CPUFLAG_8B_AND_AB_NEED_0_ARG) && ((result.val.intval & 0xff) != 0x00) - && (result.flags & MVALUE_DEFINED) - && (CPU_state.type->flags & CPUFLAG_AB_NEEDS_0_ARG)) - Throw_warning("Assembling unstable LXA #NONZERO instruction"); + && (result.flags & MVALUE_DEFINED)) { + if (imm_opcodes == 0x8b) + Throw_warning("Assembling unstable ANE #NONZERO instruction"); + else if (imm_opcodes == 0xab) + Throw_warning("Assembling unstable LXA #NONZERO instruction"); + } break; case HAM_ABS: // $ff or $ffff make_command(force_bit, &result, misc_abs[index]);