]> git.sur5r.net Git - cc65/commitdiff
Added new CPU SWEET16
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 3 Oct 2004 21:26:00 +0000 (21:26 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 3 Oct 2004 21:26:00 +0000 (21:26 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3208 b7a2c559-68d2-44c3-8de9-860c34a00d81

14 files changed:
src/ca65/ea.h [new file with mode: 0644]
src/ca65/ea65.c [new file with mode: 0644]
src/ca65/ea65.h [new file with mode: 0644]
src/ca65/easw16.c [new file with mode: 0644]
src/ca65/easw16.h [new file with mode: 0644]
src/ca65/instr.c
src/ca65/instr.h
src/ca65/make/gcc.mak
src/ca65/make/watcom.mak
src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/scanner.h
src/common/cpu.c
src/common/cpu.h

diff --git a/src/ca65/ea.h b/src/ca65/ea.h
new file mode 100644 (file)
index 0000000..dbedcd7
--- /dev/null
@@ -0,0 +1,68 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 ea65.h                                   */
+/*                                                                           */
+/*                  Effective address structure definition                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2004 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef EA_H
+#define EA_H
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* GetEA result struct */
+typedef struct EffAddr EffAddr;
+struct EffAddr {
+    /* First three fields get filled when calling GetEA */
+    unsigned long       AddrModeSet;    /* Possible addressing modes */
+    struct ExprNode*    Expr;           /* Expression if any (NULL otherwise) */
+    unsigned            Reg;            /* Register number in sweet16 mode */
+
+    /* The following fields are used inside instr.c */
+    unsigned            AddrMode;       /* Actual addressing mode used */
+    unsigned long       AddrModeBit;    /* Addressing mode as bit mask */
+    unsigned char       Opcode;         /* Opcode */
+};
+
+
+
+/* End of ea.h */
+
+#endif
+
+
+
diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c
new file mode 100644 (file)
index 0000000..98c5213
--- /dev/null
@@ -0,0 +1,205 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 ea65.c                                   */
+/*                                                                           */
+/*        65XX effective address parsing for the ca65 macroassembler         */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2004 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* ca65 */
+#include "ea.h"
+#include "ea65.h"
+#include "error.h"
+#include "expr.h"
+#include "instr.h"
+#include "nexttok.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void GetEA (EffAddr* A)
+/* Parse an effective address, return the result in A */
+{
+    unsigned long Restrictions;
+
+    /* Clear the output struct */
+    A->AddrModeSet = 0;
+    A->Expr = 0;
+
+    /* Handle an addressing size override */
+    switch (Tok) {
+        case TOK_OVERRIDE_ZP:
+            Restrictions = AM65_DIR | AM65_DIR_X | AM65_DIR_Y;
+            NextTok ();
+            break;
+
+        case TOK_OVERRIDE_ABS:
+            Restrictions = AM65_ABS | AM65_ABS_X | AM65_ABS_Y;
+            NextTok ();
+            break;
+
+        case TOK_OVERRIDE_FAR:
+            Restrictions = AM65_ABS_LONG | AM65_ABS_LONG_X;
+            NextTok ();
+            break;
+
+        default:
+            Restrictions = ~0UL;        /* None */
+            break;
+    }
+
+    /* Parse the effective address */
+    if (TokIsSep (Tok)) {
+
+       A->AddrModeSet = AM65_IMPLICIT;
+
+    } else if (Tok == TOK_HASH) {
+
+       /* #val */
+       NextTok ();
+       A->Expr  = Expression ();
+       A->AddrModeSet = AM65_IMM;
+
+    } else if (Tok == TOK_A) {
+
+       NextTok ();
+       A->AddrModeSet = AM65_ACCU;
+
+    } else if (Tok == TOK_LBRACK) {
+
+       /* [dir] or [dir],y */
+       NextTok ();
+       A->Expr = Expression ();
+       Consume (TOK_RBRACK, "']' expected");
+       if (Tok == TOK_COMMA) {
+           /* [dir],y */
+           NextTok ();
+           Consume (TOK_Y, "`Y' expected");
+           A->AddrModeSet = AM65_DIR_IND_LONG_Y;
+       } else {
+           /* [dir] */
+           A->AddrModeSet = AM65_DIR_IND_LONG;
+       }
+
+    } else if (Tok == TOK_LPAREN) {
+
+       /* One of the indirect modes */
+       NextTok ();
+       A->Expr = Expression ();
+
+       if (Tok == TOK_COMMA) {
+
+           /* (expr,X) or (rel,S),y */
+           NextTok ();
+           if (Tok == TOK_X) {
+               /* (adr,x) */
+               NextTok ();
+                       A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND;
+               ConsumeRParen ();
+           } else if (Tok == TOK_S) {
+               /* (rel,s),y */
+               NextTok ();
+               A->AddrModeSet = AM65_STACK_REL_IND_Y;
+               ConsumeRParen ();
+               ConsumeComma ();
+               Consume (TOK_Y, "`Y' expected");
+           } else {
+               Error ("Syntax error");
+           }
+
+               } else {
+
+           /* (adr) or (adr),y */
+           ConsumeRParen ();
+           if (Tok == TOK_COMMA) {
+               /* (adr),y */
+               NextTok ();
+               Consume (TOK_Y, "`Y' expected");
+               A->AddrModeSet = AM65_DIR_IND_Y;
+           } else {
+               /* (adr) */
+               A->AddrModeSet = AM65_ABS_IND | AM65_DIR_IND;
+           }
+       }
+
+    } else {
+
+       /* Remaining stuff:
+        *
+        * adr
+        * adr,x
+        * adr,y
+        * adr,s
+        */
+               A->Expr = Expression ();
+
+        if (Tok == TOK_COMMA) {
+
+            NextTok ();
+            switch (Tok) {
+
+                case TOK_X:
+                    A->AddrModeSet = AM65_ABS_LONG_X | AM65_ABS_X | AM65_DIR_X;
+                    NextTok ();
+                    break;
+
+                case TOK_Y:
+                    A->AddrModeSet = AM65_ABS_Y | AM65_DIR_Y;
+                    NextTok ();
+                    break;
+
+                case TOK_S:
+                    A->AddrModeSet = AM65_STACK_REL;
+                    NextTok ();
+                    break;
+
+                default:
+                    Error ("Syntax error");
+
+            }
+
+        } else {
+
+            A->AddrModeSet = AM65_ABS_LONG | AM65_ABS | AM65_DIR;
+
+        }
+    }
+
+    /* Apply addressing mode overrides */
+    A->AddrModeSet &= Restrictions;
+}
+
+
+
diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h
new file mode 100644 (file)
index 0000000..f5b6c32
--- /dev/null
@@ -0,0 +1,67 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 ea65.h                                   */
+/*                                                                           */
+/*        65XX effective address parsing for the ca65 macroassembler         */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef EA65_H
+#define EA65_H
+
+
+
+/*****************************************************************************/
+/*                                 Forwards                                  */
+/*****************************************************************************/
+
+
+
+struct EffAddr;
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void GetEA (EffAddr* A);
+/* Parse an effective address, return the result in A */
+
+
+
+/* End of ea65.h */
+
+#endif
+
+
+
diff --git a/src/ca65/easw16.c b/src/ca65/easw16.c
new file mode 100644 (file)
index 0000000..979eb29
--- /dev/null
@@ -0,0 +1,107 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                easw16.c                                  */
+/*                                                                           */
+/*       SWEET16 effective address parsing for the ca65 macroassembler       */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2004      Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* ca65 */
+#include "ea.h"
+#include "ea65.h"
+#include "error.h"
+#include "expr.h"
+#include "instr.h"
+#include "nexttok.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void GetSweet16EA (EffAddr* A)
+/* Parse an effective address, return the result in A */
+{
+    /* Clear the output struct */
+    A->AddrModeSet = 0;
+    A->Expr = 0;
+    A->Reg  = 0;
+
+    /* Parse the effective address */
+    if (TokIsSep (Tok)) {
+
+               A->AddrModeSet = AMSW16_IMP;
+
+    } else if (Tok == TOK_AT) {
+
+       /* @reg */
+       A->AddrModeSet = AMSW16_IND;
+       NextTok ();
+        if (Tok != TOK_REG) {
+            ErrorSkip ("Register expected");
+            A->Reg = 0;
+        } else {
+            A->Reg = (unsigned) IVal;
+            NextTok ();
+        }
+
+    } else if (Tok == TOK_REG) {
+
+        A->Reg = (unsigned) IVal;
+        NextTok ();
+
+        if (Tok == TOK_COMMA) {
+
+            /* Rx, Constant */
+            NextTok ();
+            A->Expr = Expression ();
+
+            A->AddrModeSet = AMSW16_IMM;
+
+        } else {
+
+            A->AddrModeSet = AMSW16_REG;
+
+        }
+
+    } else {
+
+        /* OPC  ea */
+        A->Expr = Expression ();
+        A->AddrModeSet = AMSW16_BRA;
+
+    }
+}
+
+
+
diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h
new file mode 100644 (file)
index 0000000..3c8af69
--- /dev/null
@@ -0,0 +1,68 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                easw16.h                                  */
+/*                                                                           */
+/*       SWEET16 effective address parsing for the ca65 macroassembler       */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2004      Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef EASW16_H
+#define EASW16_H
+
+
+
+/*****************************************************************************/
+/*                                 Forwards                                  */
+/*****************************************************************************/
+
+
+
+struct EffAddr;
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void GetSweet16EA (EffAddr* A);
+/* Parse an effective address, return the result in A */
+
+
+
+/* End of easw16.h */
+
+#endif
+
+
+
+                
index 33f364c1a8d5f9df7becf1414b390863a083092c..1cfc5ba30243a9f40905b2ef86b93ac6883e4cff 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/* (C) 1998-2004 Ullrich von Bassewitz                                       */
 /*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -48,6 +48,8 @@
 /* ca65 */
 #include "asserts.h"
 #include "ea.h"
+#include "ea65.h"
+#include "easw16.h"
 #include "error.h"
 #include "expr.h"
 #include "global.h"
@@ -76,6 +78,8 @@ static void PutSEP (const InsDesc* Ins);
 static void PutJMP (const InsDesc* Ins);
 static void PutRTS (const InsDesc* Ins);
 static void PutAll (const InsDesc* Ins);
+static void PutSweet16 (const InsDesc* Ins);
+static void PutSweet16Branch (const InsDesc* Ins);
 
 
 
@@ -419,7 +423,7 @@ static const struct {
     unsigned Count;
     InsDesc  Ins[INS_COUNT_65816];
 } InsTab65816 = {
-    INS_COUNT_65816,             
+    INS_COUNT_65816,
     {
                { "ADC",  0x0b8f6fc, 0x60, 0, PutAll },
                { "AND",  0x0b8f6fc, 0x20, 0, PutAll },
@@ -530,6 +534,43 @@ static const struct {
 #include "sunplus.inc"
 #endif
 
+/* Instruction table for the SWEET16 pseudo CPU */
+#define INS_COUNT_SWEET16 27
+static const struct {
+    unsigned Count;
+    InsDesc  Ins[INS_COUNT_SWEET16];
+} InsTabSweet16 = {
+    INS_COUNT_SWEET16,
+    {
+        { "ADD",  AMSW16_REG,              0xA0, 0, PutSweet16 },
+        { "BC",   AMSW16_BRA,              0x03, 0, PutSweet16Branch },
+        { "BK",   AMSW16_IMP,              0x0A, 0, PutSweet16 },
+        { "BM",   AMSW16_BRA,              0x05, 0, PutSweet16Branch },
+        { "BM1",  AMSW16_BRA,              0x08, 0, PutSweet16Branch },
+        { "BNC",  AMSW16_BRA,              0x02, 0, PutSweet16Branch },
+        { "BNM1", AMSW16_BRA,              0x09, 0, PutSweet16Branch },
+        { "BNZ",  AMSW16_BRA,              0x07, 0, PutSweet16Branch },
+        { "BP",   AMSW16_BRA,              0x04, 0, PutSweet16Branch },
+        { "BR",   AMSW16_BRA,              0x01, 0, PutSweet16Branch },
+        { "BS",   AMSW16_BRA,              0x0B, 0, PutSweet16Branch },
+        { "BZ",   AMSW16_BRA,              0x06, 0, PutSweet16Branch },
+        { "CPR",  AMSW16_REG,              0xD0, 0, PutSweet16 },
+        { "DCR",  AMSW16_REG,              0xF0, 0, PutSweet16 },
+        { "INR",  AMSW16_REG,              0xE0, 0, PutSweet16 },
+        { "LD",   AMSW16_REG | AMSW16_IND, 0x00, 1, PutSweet16 },
+        { "LDD",  AMSW16_IND,              0x60, 0, PutSweet16 },
+        { "POP",  AMSW16_IND,              0x80, 0, PutSweet16 },
+        { "POPD", AMSW16_IND,              0xC0, 0, PutSweet16 },
+        { "RS",   AMSW16_IMP,              0x0B, 0, PutSweet16 },
+        { "RTN",  AMSW16_IMP,              0x00, 0, PutSweet16 },
+        { "SET",  AMSW16_IMM,              0x10, 0, PutSweet16 },
+        { "ST",   AMSW16_REG | AMSW16_IND, 0x10, 1, PutSweet16 },
+        { "STD",  AMSW16_IND,              0x70, 0, PutSweet16 },
+        { "STP",  AMSW16_IND,              0x90, 0, PutSweet16 },
+        { "SUB",  AMSW16_IMM,              0xB0, 0, PutSweet16 },
+    }
+};
+
 
 
 /* An array with instruction tables */
@@ -541,14 +582,17 @@ static const InsTable* InsTabs[CPU_COUNT] = {
     (const InsTable*) &InsTab65816,
 #ifdef SUNPLUS
     (const InsTable*) &InsTabSunPlus,
+#else
+    NULL,
 #endif
+    (const InsTable*) &InsTabSweet16,
 };
 const InsTable* InsTab = (const InsTable*) &InsTab6502;
 
-/* Table to build the effective opcode from a base opcode and an addressing
- * mode.
+/* Table to build the effective 65xx opcode from a base opcode and an
+ * addressing mode.
  */
-unsigned char EATab [9][AMI_COUNT] = {
+static unsigned char EATab[9][AM65I_COUNT] = {
     {   /* Table 0 */
        0x00, 0x00, 0x05, 0x0D, 0x0F, 0x15, 0x1D, 0x1F,
        0x00, 0x19, 0x12, 0x00, 0x07, 0x11, 0x17, 0x01,
@@ -605,8 +649,20 @@ unsigned char EATab [9][AMI_COUNT] = {
     },
 };
 
-/* Table that encodes the additional bytes for each instruction */
-unsigned char ExtBytes [AMI_COUNT] = {
+/* Table to build the effective SWEET16 opcode from a base opcode and an
+ * addressing mode.
+ */
+static unsigned char Sweet16EATab[2][AMSW16I_COUNT] = {
+    {   /* Table 0 */
+               0x00, 0x00, 0x00, 0x00, 0x00,
+    },
+    {   /* Table 1 */
+               0x00, 0x00, 0x00, 0x40, 0x20,
+    },
+};
+
+/* Table that encodes the additional bytes for each 65xx instruction */
+unsigned char ExtBytes[AM65I_COUNT] = {
     0,         /* Implicit */
     0,         /* Accu */
     1,         /* Direct */
@@ -634,10 +690,19 @@ unsigned char ExtBytes [AMI_COUNT] = {
     2          /* Blockmove */
 };
 
+/* Table that encodes the additional bytes for each SWEET16 instruction */
+static unsigned char Sweet16ExtBytes[AMSW16I_COUNT] = {
+    0,          /* AMSW16_IMP */
+    1,          /* AMSW16_BRA */
+    2,          /* AMSW16_IMM */
+    0,          /* AMSW16_IND */
+    0,          /* AMSW16_REG */
+};
+
 
 
 /*****************************************************************************/
-/*                            Handler functions                             */
+/*                   Handler functions for 6502 derivates                    */
 /*****************************************************************************/
 
 
@@ -680,11 +745,11 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
         switch (ED.AddrSize) {
 
             case ADDR_SIZE_ABS:
-                A->AddrModeSet &= ~AM_SET_ZP;
+                A->AddrModeSet &= ~AM65_SET_ZP;
                 break;
 
             case ADDR_SIZE_FAR:
-                A->AddrModeSet &= ~(AM_SET_ZP | AM_SET_ABS);
+                A->AddrModeSet &= ~(AM65_SET_ZP | AM65_SET_ABS);
                 break;
         }
 
@@ -706,8 +771,8 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
      * emit a warning. This warning protects against a typo, where the '#'
      * for the immediate operand is omitted.
      */
-    if (A->Expr && (Ins->AddrMode & AM_IMM)                &&
-        (A->AddrModeSet & (AM_DIR | AM_ABS | AM_ABS_LONG)) &&
+    if (A->Expr && (Ins->AddrMode & AM65_IMM)                    &&
+        (A->AddrModeSet & (AM65_DIR | AM65_ABS | AM65_ABS_LONG)) &&
         ExtBytes[A->AddrMode] == 1) {
 
         /* Found, check the expression */
@@ -745,7 +810,7 @@ static void EmitCode (EffAddr* A)
            break;
 
        case 2:
-           if (CPU == CPU_65816 && (A->AddrModeBit & (AM_ABS | AM_ABS_X | AM_ABS_Y))) {
+           if (CPU == CPU_65816 && (A->AddrModeBit & (AM65_ABS | AM65_ABS_X | AM65_ABS_Y))) {
                /* This is a 16 bit mode that uses an address. If in 65816,
                 * mode, force this address into 16 bit range to allow
                 * addressing inside a 64K segment.
@@ -859,11 +924,11 @@ static void PutREP (const InsDesc* Ins)
        } else {
            if (Val & 0x10) {
                /* Index registers to 16 bit */
-               ExtBytes[AMI_IMM_INDEX] = 2;
+               ExtBytes[AM65I_IMM_INDEX] = 2;
            }
            if (Val & 0x20) {
                /* Accu to 16 bit */
-               ExtBytes[AMI_IMM_ACCU] = 2;
+               ExtBytes[AM65I_IMM_ACCU] = 2;
            }
        }
     }
@@ -887,11 +952,11 @@ static void PutSEP (const InsDesc* Ins)
        } else {
            if (Val & 0x10) {
                /* Index registers to 8 bit */
-               ExtBytes [AMI_IMM_INDEX] = 1;
+               ExtBytes[AM65I_IMM_INDEX] = 1;
            }
            if (Val & 0x20) {
                /* Accu to 8 bit */
-               ExtBytes [AMI_IMM_ACCU] = 1;
+               ExtBytes[AM65I_IMM_ACCU] = 1;
            }
        }
     }
@@ -912,7 +977,7 @@ static void PutJMP (const InsDesc* Ins)
     if (EvalEA (Ins, &A)) {
 
         /* Check for indirect addressing */
-        if (A.AddrModeBit & AM_ABS_IND) {
+        if (A.AddrModeBit & AM65_ABS_IND) {
 
             /* Compare the low byte of the expression to 0xFF to check for
              * a page cross. Be sure to use a copy of the expression otherwise
@@ -963,7 +1028,68 @@ static void PutAll (const InsDesc* Ins)
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                       Handler functions for SWEET16                       */
+/*****************************************************************************/
+
+
+
+static void PutSweet16 (const InsDesc* Ins)
+/* Handle a generic sweet16 instruction */
+{
+    EffAddr A;
+
+    /* Evaluate the addressing mode used */
+    GetSweet16EA (&A);
+
+    /* From the possible addressing modes, remove the ones that are invalid
+     * for this instruction or CPU.
+     */
+    A.AddrModeSet &= Ins->AddrMode;
+
+    /* Check if we have any adressing modes left */
+    if (A.AddrModeSet == 0) {
+               Error ("Illegal addressing mode");
+               return;
+    }
+    A.AddrMode    = BitFind (A.AddrModeSet);
+    A.AddrModeBit = (0x01UL << A.AddrMode);
+
+    /* Build the opcode */
+    A.Opcode = Ins->BaseCode | Sweet16EATab[Ins->ExtCode][A.AddrMode] | A.Reg;
+
+    /* Check how many extension bytes are needed and output the instruction */
+    switch (Sweet16ExtBytes[A.AddrMode]) {
+
+        case 0:
+           Emit0 (A.Opcode);
+           break;
+
+       case 1:
+           Emit1 (A.Opcode, A.Expr);
+           break;
+
+       case 2:
+            Emit2 (A.Opcode, A.Expr);
+           break;
+
+       default:
+           Internal ("Invalid operand byte count: %u", Sweet16ExtBytes[A.AddrMode]);
+
+    }
+}
+
+
+
+static void PutSweet16Branch (const InsDesc* Ins)
+/* Handle a sweet16 branch instruction */
+{
+    EmitPCRel (Ins->BaseCode, GenBranchExpr (2), 1);
+}
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
 /*****************************************************************************/
 
 
index de752fd63cc4eec1563636216dc2dd072984e789..4fa99090db5c96fd4378ef0b71973dde362ed76c 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/* (C) 1998-2004 Ullrich von Bassewitz                                       */
 /*               Römerstrasse 52                                             */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -44,7 +44,7 @@
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                       Data for 6502 and successors                        */
 /*****************************************************************************/
 
 
  * When assembling for the 6502 or 65C02, all addressing modes that are not
  * available on these CPUs are removed before doing any checks.
  */
-#define AM_IMPLICIT                    0x00000003UL
-#define AM_ACCU                        0x00000002UL
-#define AM_DIR                 0x00000004UL
-#define AM_ABS                 0x00000008UL
-#define AM_ABS_LONG            0x00000010UL
-#define AM_DIR_X               0x00000020UL
-#define AM_ABS_X               0x00000040UL
-#define AM_ABS_LONG_X          0x00000080UL
-#define AM_DIR_Y                       0x00000100UL
-#define AM_ABS_Y                       0x00000200UL
-#define AM_DIR_IND                     0x00000400UL
-#define AM_ABS_IND                     0x00000800UL
-#define AM_DIR_IND_LONG                0x00001000UL
-#define AM_DIR_IND_Y                   0x00002000UL
-#define AM_DIR_IND_LONG_Y              0x00004000UL
-#define AM_DIR_X_IND                   0x00008000UL
-#define AM_ABS_X_IND                   0x00010000UL
-#define AM_REL                         0x00020000UL
-#define AM_REL_LONG                    0x00040000UL
-#define AM_STACK_REL                   0x00080000UL
-#define AM_STACK_REL_IND_Y             0x00100000UL
-#define AM_IMM_ACCU            0x00200000UL
-#define AM_IMM_INDEX           0x00400000UL
-#define AM_IMM_IMPLICIT                0x00800000UL
-#define AM_IMM                         (AM_IMM_ACCU | AM_IMM_INDEX | AM_IMM_IMPLICIT)
-#define AM_BLOCKMOVE                   0x01000000UL
+#define AM65_IMPLICIT                  0x00000003UL
+#define AM65_ACCU                      0x00000002UL
+#define AM65_DIR               0x00000004UL
+#define AM65_ABS               0x00000008UL
+#define AM65_ABS_LONG                  0x00000010UL
+#define AM65_DIR_X             0x00000020UL
+#define AM65_ABS_X             0x00000040UL
+#define AM65_ABS_LONG_X                0x00000080UL
+#define AM65_DIR_Y                     0x00000100UL
+#define AM65_ABS_Y                     0x00000200UL
+#define AM65_DIR_IND                   0x00000400UL
+#define AM65_ABS_IND                   0x00000800UL
+#define AM65_DIR_IND_LONG              0x00001000UL
+#define AM65_DIR_IND_Y                 0x00002000UL
+#define AM65_DIR_IND_LONG_Y            0x00004000UL
+#define AM65_DIR_X_IND                 0x00008000UL
+#define AM65_ABS_X_IND                 0x00010000UL
+#define AM65_REL                       0x00020000UL
+#define AM65_REL_LONG                  0x00040000UL
+#define AM65_STACK_REL                 0x00080000UL
+#define AM65_STACK_REL_IND_Y           0x00100000UL
+#define AM65_IMM_ACCU          0x00200000UL
+#define AM65_IMM_INDEX         0x00400000UL
+#define AM65_IMM_IMPLICIT              0x00800000UL
+#define AM65_IMM                       (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT)
+#define AM65_BLOCKMOVE                 0x01000000UL
 
 /* Bitmask for all ZP operations that have correspondent ABS ops */
-#define AM_SET_ZP      (AM_DIR | AM_DIR_X | AM_DIR_Y | AM_DIR_IND | AM_DIR_X_IND)
+#define AM65_SET_ZP    (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND)
 
 /* Bitmask for all ABS operations that have correspondent FAR ops */
-#define AM_SET_ABS      (AM_ABS | AM_ABS_X)
+#define AM65_SET_ABS      (AM65_ABS | AM65_ABS_X)
 
 /* Bit numbers and count */
-#define AMI_IMM_ACCU           21
-#define AMI_IMM_INDEX          22
-#define AMI_COUNT              25
+#define AM65I_IMM_ACCU         21
+#define AM65I_IMM_INDEX                22
+#define AM65I_COUNT            25
 
 
 
@@ -117,18 +117,30 @@ struct InsTable {
 /* The instruction table for the currently active CPU */
 extern const InsTable* InsTab;
 
-/* Table to build the effective opcode from a base opcode and an addressing
- * mode.
- */
-extern unsigned char EATab [9][AMI_COUNT];
-
 /* Table that encodes the additional bytes for each instruction */
-extern unsigned char ExtBytes [AMI_COUNT];
+extern unsigned char ExtBytes[AM65I_COUNT];
+
+
+
+/*****************************************************************************/
+/*                      Data for the SWEET16 pseudo CPU                      */
+/*****************************************************************************/
+
+
+
+/* SWEET16 addressing modes */
+#define AMSW16_IMP      0x0001          /* Implicit */
+#define AMSW16_BRA      0x0002          /* A branch */
+#define AMSW16_IMM      0x0004          /* Immediate */
+#define AMSW16_IND      0x0008          /* Indirect */
+#define AMSW16_REG      0x0010          /* Register */
+
+#define AMSW16I_COUNT   5               /* Number of addressing modes */
 
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                          Code                                    */
 /*****************************************************************************/
 
 
index 950d725dcaa5f502d9e196d3903d999e24199874..97de9ebda191c521f5a1cd4e5843846f1ec813ef 100644 (file)
@@ -14,7 +14,8 @@ OBJS =  anonname.o      \
         asserts.o       \
         condasm.o      \
        dbginfo.o       \
-       ea.o            \
+               ea65.o          \
+        easw16.o        \
         enum.o          \
         error.o                \
         expr.o         \
index fa7d9ee652fe57ac5326309fd16fa421397e5b55..16b4fa109461351fc506af104b9665ed50f7c3be 100644 (file)
@@ -63,7 +63,8 @@ OBJS =        anonname.obj    \
         asserts.obj     \
         condasm.obj    \
        dbginfo.obj     \
-       ea.obj          \
+       ea65.obj        \
+        easw16.obj      \
         enum.obj        \
        error.obj       \
        expr.obj        \
index f68239bcd3984ea98ce3fc885efa208f0519e7df..d0aaff6dfea43580c9dbc299421a7bd4c559ca94 100644 (file)
@@ -269,7 +269,7 @@ static void DoA16 (void)
        Error ("Command is only valid in 65816 mode");
     } else {
                /* Immidiate mode has two extension bytes */
-       ExtBytes [AMI_IMM_ACCU] = 2;
+       ExtBytes [AM65I_IMM_ACCU] = 2;
     }
 }
 
@@ -282,7 +282,7 @@ static void DoA8 (void)
        Error ("Command is only valid in 65816 mode");
     } else {
        /* Immidiate mode has one extension byte */
-       ExtBytes [AMI_IMM_ACCU] = 1;
+       ExtBytes [AM65I_IMM_ACCU] = 1;
     }
 }
 
@@ -524,7 +524,7 @@ static void DoConDes (void)
 {
     static const char* Keys[] = {
                "CONSTRUCTOR",
-       "DESTRUCTOR", 
+       "DESTRUCTOR",
         "INTERRUPTOR",
     };
     char Name [sizeof (SVal)];
@@ -568,7 +568,7 @@ static void DoConDes (void)
     /* Parse the remainder of the line and export the symbol */
     ConDes (Name, (unsigned) Type);
 }
-                      
+
 
 
 static void DoConstructor (void)
@@ -943,7 +943,7 @@ static void DoI16 (void)
        Error ("Command is only valid in 65816 mode");
     } else {
                /* Immidiate mode has two extension bytes */
-       ExtBytes [AMI_IMM_INDEX] = 2;
+       ExtBytes [AM65I_IMM_INDEX] = 2;
     }
 }
 
@@ -956,7 +956,7 @@ static void DoI8 (void)
        Error ("Command is only valid in 65816 mode");
     } else {
        /* Immidiate mode has one extension byte */
-       ExtBytes [AMI_IMM_INDEX] = 1;
+       ExtBytes [AM65I_IMM_INDEX] = 1;
     }
 }
 
@@ -1501,12 +1501,16 @@ static void DoSetCPU (void)
     if (Tok != TOK_STRCON) {
        ErrorSkip ("String constant expected");
     } else {
-        /* Try to find the CPU, then skip the identifier */
+        /* Try to find the CPU */
         cpu_t CPU = FindCPU (SVal);
-        NextTok ();
 
         /* Switch to the new CPU */
         SetCPU (CPU);
+
+        /* Skip the identifier. If the CPU switch was successful, the scanner
+         * will treat the input now correctly for the new CPU.
+         */
+        NextTok ();
     }
 }
 
index 9b8a6dfc262cc6e3ddb4bddf0322b835efb9ee08..91c091212d8f3e214c84eafe300eabeb2fb293f2 100644 (file)
@@ -640,6 +640,32 @@ static unsigned ReadStringConst (int StringTerm)
 
 
 
+static int Sweet16Reg (const char* Ident)
+/* Check if the given identifier is a sweet16 register. Return -1 if this is
+ * not the case, return the register number otherwise.
+ */
+{
+    unsigned RegNum;
+    char Check;
+
+    if (Ident[0] != 'r' && Ident[0] != 'R') {
+        return -1;
+    }
+    if (!IsDigit (Ident[1])) {
+        return -1;
+    }
+
+    if (sscanf (Ident+1, "%u%c", &RegNum, &Check) != 1 || RegNum > 15) {
+        /* Invalid register */
+        return -1;
+    }
+
+    /* The register number is valid */
+    return (int) RegNum;
+}
+
+
+
 void NextRawTok (void)
 /* Read the next raw token from the input stream */
 {
@@ -791,6 +817,15 @@ Again:
        return;
     }
 
+    /* Indirect op for sweet16 cpu. Must check this before checking for local
+     * symbols, because these may also use the '@' symbol.
+     */
+    if (CPU == CPU_SWEET16 && C == '@') {
+        NextChar ();
+        Tok = TOK_AT;
+        return;
+    }
+
     /* Local symbol? */
     if (C == LocalStart) {
 
@@ -834,7 +869,7 @@ Again:
                     if (C == ':') {
                         NextChar ();
                         Tok = TOK_OVERRIDE_FAR;
-                       return;
+                       return;
                     }
                    break;
 
@@ -854,14 +889,21 @@ Again:
                     if (C == ':') {
                         NextChar ();
                         Tok = TOK_OVERRIDE_ZP;
-                       return;
+                       return;
                     }
                     break;
 
                default:
                    break;
            }
-       }
+
+       } else if (CPU == CPU_SWEET16 && (IVal = Sweet16Reg (SVal)) >= 0) {
+
+            /* A sweet16 register number in sweet16 mode */
+            Tok = TOK_REG;
+            return;
+
+        }
 
        /* Check for define style macro */
                if (IsDefine (SVal)) {
@@ -1147,7 +1189,7 @@ int TokHasSVal (enum Token Tok)
 int TokHasIVal (enum Token Tok)
 /* Return true if the given token has an attached IVal */
 {
-    return (Tok == TOK_INTCON || Tok == TOK_CHARCON);
+    return (Tok == TOK_INTCON || Tok == TOK_CHARCON || Tok == TOK_REG);
 }
 
 
index 5c19a37f7e2ff6f42e5cc7f26c4a12fe475201a5..cf98dff0286625bf4bda2f2f50cf6a6c8bb17a02 100644 (file)
@@ -62,10 +62,11 @@ enum Token {
     TOK_CHARCON,       /* Character constant */
     TOK_STRCON,                /* String constant */
 
-    TOK_A,             /* A)ccu */
+    TOK_A,             /* A)ccumulator */
     TOK_X,             /* X register */
     TOK_Y,             /* Y register */
     TOK_S,             /* S register */
+    TOK_REG,            /* Sweet16 R.. register (in sweet16 mode) */
 
     TOK_ASSIGN,         /* := */
     TOK_ULABEL,                /* :++ or :-- */
@@ -108,6 +109,7 @@ enum Token {
     TOK_RBRACK,                /* ] */
     TOK_LCURLY,         /* { */
     TOK_RCURLY,         /* } */
+    TOK_AT,             /* @ - in Sweet16 mode */
 
     TOK_OVERRIDE_ZP,    /* z: */
     TOK_OVERRIDE_ABS,   /* a: */
@@ -194,7 +196,7 @@ enum Token {
     TOK_LINECONT,
     TOK_LIST,
     TOK_LISTBYTES,
-    TOK_LOBYTE,     
+    TOK_LOBYTE,
     TOK_LOCAL,
     TOK_LOCALCHAR,
     TOK_LOWORD,
index d83ab53db7d3d38db715fae074d3b97b29ddefdf..52ad2bb5bff8a8d8d0740e92694d08ff75e5d1fb 100644 (file)
@@ -57,6 +57,7 @@ const char* CPUNames[CPU_COUNT] = {
     "65C02",
     "65816",
     "sunplus",
+    "sweet16",
 };
 
 /* Tables with CPU instruction sets */
@@ -66,7 +67,8 @@ const unsigned CPUIsets[CPU_COUNT] = {
     CPU_ISET_6502 | CPU_ISET_65SC02,
     CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02,
     CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_65816,
-    CPU_ISET_SUNPLUS
+    CPU_ISET_SUNPLUS,
+    CPU_ISET_SWEET16,
 };
 
 
index e0f3387da49884b1d2f778928471c69c9653c926..f9720bd4567db8b3212bf6d71bc45fa6c2ae956f 100644 (file)
@@ -53,6 +53,7 @@ typedef enum {
     CPU_65C02,
     CPU_65816,
     CPU_SUNPLUS,               /* Not in the freeware version - sorry */
+    CPU_SWEET16,
     CPU_COUNT                          /* Number of different CPUs */
 } cpu_t;
 
@@ -63,7 +64,8 @@ enum {
     CPU_ISET_65SC02     = 1 << CPU_65SC02,
     CPU_ISET_65C02      = 1 << CPU_65C02,
     CPU_ISET_65816      = 1 << CPU_65816,
-    CPU_ISET_SUNPLUS    = 1 << CPU_SUNPLUS
+    CPU_ISET_SUNPLUS    = 1 << CPU_SUNPLUS,
+    CPU_ISET_SWEET16    = 1 << CPU_SWEET16,
 };
 
 /* CPU used */
@@ -81,7 +83,7 @@ extern const unsigned CPUIsets[CPU_COUNT];
 /*                                          Code                                    */
 /*****************************************************************************/
 
-
+                                           
 
 cpu_t FindCPU (const char* Name);
 /* Find a CPU by name and return the target id. CPU_UNKNOWN is returned if