]> git.sur5r.net Git - cc65/commitdiff
Completed assertions, add auto assertion for jmp (abs) bug
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 6 Jun 2003 20:47:59 +0000 (20:47 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 6 Jun 2003 20:47:59 +0000 (20:47 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2203 b7a2c559-68d2-44c3-8de9-860c34a00d81

12 files changed:
src/ca65/asserts.c [new file with mode: 0644]
src/ca65/asserts.h [new file with mode: 0644]
src/ca65/ea.c
src/ca65/ea.h
src/ca65/expr.c
src/ca65/expr.h
src/ca65/instr.c
src/ca65/main.c
src/ca65/make/gcc.mak
src/ca65/make/watcom.mak
src/ca65/pseudo.c
src/common/assertdefs.h [new file with mode: 0644]

diff --git a/src/ca65/asserts.c b/src/ca65/asserts.c
new file mode 100644 (file)
index 0000000..25f5178
--- /dev/null
@@ -0,0 +1,137 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 asserts.c                                 */
+/*                                                                           */
+/*               Linker assertions for the ca65 crossassembler               */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "coll.h"
+#include "xmalloc.h"
+
+/* ca65 */
+#include "asserts.h"
+#include "expr.h"
+#include "objfile.h"
+#include "scanner.h"
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* An assertion entry */
+typedef struct Assertion Assertion;
+struct Assertion {
+    ExprNode*   Expr;           /* Expression to evaluate */
+    unsigned    Action;         /* Action to take */
+    unsigned    Msg;            /* Message to print (if any) */
+    FilePos     Pos;            /* File position of assertion */
+};
+
+/* Collection with all assertions for a module */
+static Collection Assertions = STATIC_COLLECTION_INITIALIZER;
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+static Assertion* NewAssertion (ExprNode* Expr, unsigned Action, unsigned Msg)
+/* Create a new Assertion struct and return it */
+{
+    /* Allocate memory */
+    Assertion* A = xmalloc (sizeof (Assertion));
+
+    /* Initialize the fields */
+    A->Expr     = Expr;
+    A->Action   = Action;
+    A->Msg      = Msg;
+    A->Pos      = CurPos;
+
+    /* Return the new struct */
+    return A;
+}
+
+
+
+void AddAssertion (ExprNode* Expr, unsigned Action, unsigned Msg)
+/* Add an assertion to the assertion table */
+{
+    /* Add an assertion object to the table */
+    CollAppend (&Assertions, NewAssertion (Expr, Action, Msg));
+}
+
+
+
+void WriteAssertions (void)
+/* Write the assertion table to the object file */
+{
+    unsigned I;
+
+    /* Get the number of strings in the string pool */
+    unsigned Count = CollCount (&Assertions);
+
+    /* Tell the object file module that we're about to start the assertions */
+    ObjStartAssertions ();
+
+    /* Write the string count to the list */
+    ObjWriteVar (Count);
+
+    /* Write the assertions */
+    for (I = 0; I < Count; ++I) {
+
+        /* Get the next assertion */
+        Assertion* A = CollAtUnchecked (&Assertions, I);
+
+        /* Finalize the expression */
+        A->Expr = FinalizeExpr (A->Expr);
+
+        /* Write it to the file */
+        WriteExpr (A->Expr);
+        ObjWriteVar (A->Action);
+        ObjWriteVar (A->Msg);
+        ObjWritePos (&A->Pos);
+    }
+
+    /* Done writing the assertions */
+    ObjEndAssertions ();
+}
+
+
+
+                 
diff --git a/src/ca65/asserts.h b/src/ca65/asserts.h
new file mode 100644 (file)
index 0000000..0aef773
--- /dev/null
@@ -0,0 +1,71 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 asserts.h                                 */
+/*                                                                           */
+/*               Linker assertions for the ca65 crossassembler               */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 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 ASSERTS_H
+#define ASSERTS_H
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* Forwards */
+struct ExprNode;
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void AddAssertion (struct ExprNode* Expr, unsigned Action, unsigned Msg);
+/* Add an assertion to the assertion table */
+
+void WriteAssertions (void);
+/* Write the assertion table to the object file */
+
+
+
+/* End of asserts.h */
+
+#endif
+
+
+
index 9bd5d3010ce00b1a38768c458efa1d72a9dcc94d..00303a47f3f6c078d21a9fcce689773c3ec8dc7d 100644 (file)
@@ -7,9 +7,9 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 
+/* ld65 */
 #include "error.h"
 #include "expr.h"
 #include "instr.h"
 #include "nexttok.h"
 #include "ea.h"
 
-
+               
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                          Code                                    */
 /*****************************************************************************/
 
 
 
-void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
-/* Parse an effective address, return the possible modes in AddrMode, and the
- * expression involved (if any) in Expr.
- */
+void GetEA (EffAddr* A)
+/* Parse an effective address, return the result in A */
 {
-    /* Clear the expressions */
-    *Bank = *Expr = 0;
+    /* Clear the output struct */
+    A->AddrModeSet = 0;
+    A->Bank = 0;
+    A->Expr = 0;
 
 
     if (TokIsSep (Tok)) {
 
-       *AddrMode = AM_IMPLICIT;
+       A->AddrModeSet = AM_IMPLICIT;
 
     } else if (Tok == TOK_HASH) {
 
        /* #val */
        NextTok ();
-       *Expr = Expression ();
-       *AddrMode = AM_IMM;
+       A->Expr  = Expression ();
+       A->AddrModeSet = AM_IMM;
 
     } else if (Tok == TOK_A) {
 
        NextTok ();
-       *AddrMode = AM_ACCU;
+       A->AddrModeSet = AM_ACCU;
 
     } else if (Tok == TOK_LBRACK) {
 
        /* [dir] or [dir],y */
        NextTok ();
-       *Expr = Expression ();
+       A->Expr = Expression ();
        Consume (TOK_RBRACK, ERR_RBRACK_EXPECTED);
        if (Tok == TOK_COMMA) {
            /* [dir],y */
            NextTok ();
            Consume (TOK_Y, ERR_Y_EXPECTED);
-           *AddrMode = AM_DIR_IND_LONG_Y;
+           A->AddrModeSet = AM_DIR_IND_LONG_Y;
        } else {
            /* [dir] */
-           *AddrMode = AM_DIR_IND_LONG;
+           A->AddrModeSet = AM_DIR_IND_LONG;
        }
 
     } else if (Tok == TOK_LPAREN) {
 
        /* One of the indirect modes */
        NextTok ();
-       *Expr = Expression ();
+       A->Expr = Expression ();
 
        if (Tok == TOK_COMMA) {
 
            /* (expr,X) or (rel,S),y */
            NextTok ();
            if (Tok == TOK_X) {
-               /* (adr,x) */
-               NextTok ();
-                       *AddrMode = AM_ABS_X_IND | AM_DIR_X_IND;
-               ConsumeRParen ();
+               /* (adr,x) */
+               NextTok ();
+                       A->AddrModeSet = AM_ABS_X_IND | AM_DIR_X_IND;
+               ConsumeRParen ();
            } else if (Tok == TOK_S) {
-               /* (rel,s),y */
+               /* (rel,s),y */
                NextTok ();
-               *AddrMode = AM_STACK_REL_IND_Y;
+               A->AddrModeSet = AM_STACK_REL_IND_Y;
                ConsumeRParen ();
                ConsumeComma ();
                Consume (TOK_Y, ERR_Y_EXPECTED);
@@ -122,10 +123,10 @@ void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
                /* (adr),y */
                NextTok ();
                Consume (TOK_Y, ERR_Y_EXPECTED);
-               *AddrMode = AM_DIR_IND_Y;
+               A->AddrModeSet = AM_DIR_IND_Y;
            } else {
                /* (adr) */
-               *AddrMode = AM_ABS_IND | AM_DIR_IND;
+               A->AddrModeSet = AM_ABS_IND | AM_DIR_IND;
            }
        }
 
@@ -140,22 +141,22 @@ void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
         * adr,y
         * adr,s
         */
-               *Expr = Expression ();
+               A->Expr = Expression ();
 
                if (Tok == TOK_DOT) {
 
                    /* Expr was a bank specification: bank.adr or bank.adr,x */
-                   *Bank = *Expr;
+                   A->Bank = A->Expr;
                    NextTok ();
-                   *Expr = Expression ();
+                   A->Expr = Expression ();
                    if (Tok == TOK_COMMA) {
-                       /* bank.adr,x */
-                       NextTok ();
-                       Consume (TOK_X, ERR_X_EXPECTED);
-                       *AddrMode = AM_ABS_LONG_X;
+                       /* bank.adr,x */
+                       NextTok ();
+                       Consume (TOK_X, ERR_X_EXPECTED);
+                       A->AddrModeSet = AM_ABS_LONG_X;
                    } else {
                        /* bank.adr */
-                       *AddrMode = AM_ABS_LONG;
+                       A->AddrModeSet = AM_ABS_LONG;
                    }
 
        } else {
@@ -166,17 +167,17 @@ void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
                switch (Tok) {
 
                    case TOK_X:
-                               *AddrMode = AM_ABS_X | AM_DIR_X;
+                               A->AddrModeSet = AM_ABS_X | AM_DIR_X;
                        NextTok ();
                        break;
 
                    case TOK_Y:
-                       *AddrMode = AM_ABS_Y | AM_DIR_Y;
+                       A->AddrModeSet = AM_ABS_Y | AM_DIR_Y;
                        NextTok ();
                        break;
 
                    case TOK_S:
-                       *AddrMode = AM_STACK_REL;
+                       A->AddrModeSet = AM_STACK_REL;
                        NextTok ();
                        break;
 
@@ -185,9 +186,9 @@ void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
 
                }
 
-           } else {  
+           } else {
 
-               *AddrMode = AM_ABS | AM_DIR;
+               A->AddrModeSet = AM_ABS | AM_DIR;
 
            }
        }
index 8d3c88a8de3b4d8268ebfc850656a671e1d56817..9bc6c1ba330088053b9a934083028c3b6c6535f6 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                  ea.h                                    */
+/*                                  ea.h                                    */
 /*                                                                           */
 /*          Effective address parsing for the ca65 macroassembler           */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (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       */
 
 
 
-#include "expr.h"
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
 
 
 
-/*****************************************************************************/
-/*                                          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) */
+    struct ExprNode*    Bank;           /* Bank expression if any */
+
+    /* 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 */
+};
 
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                          Code                                    */
 /*****************************************************************************/
 
 
 
-void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank);
-/* Parse an effective address, return the possible modes in AddrMode, and the
- * expression involved (if any) in Expr.
- */
+void GetEA (EffAddr* A);
+/* Parse an effective address, return the result in A */
 
 
 
index 42c90d1542d3b6ea615b89fc677419b846f7b88f..af26c0dfe47a0f25f74840507b7ac14bf58f46b3 100644 (file)
@@ -7,9 +7,9 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -951,6 +951,18 @@ long ConstExpression (void)
 
 
 
+void FreeExpr (ExprNode* Root)
+/* Free the expression, Root is pointing to. */
+{
+    if (Root) {
+       FreeExpr (Root->Left);
+       FreeExpr (Root->Right);
+       FreeExprNode (Root);
+    }
+}
+
+
+
 ExprNode* LiteralExpr (long Val)
 /* Return an expression tree that encodes the given literal value */
 {
@@ -1050,14 +1062,16 @@ ExprNode* ULabelExpr (unsigned Num)
 
 
 
-void FreeExpr (ExprNode* Root)
-/* Free the expression, Root is pointing to. */
+ExprNode* ForceByteExpr (ExprNode* Expr)
+/* Force the given expression into a byte and return the result */
 {
-    if (Root) {
-       FreeExpr (Root->Left);
-       FreeExpr (Root->Right);
-       FreeExprNode (Root);
-    }
+    /* Use the low byte operator to force the expression into byte size */
+    ExprNode* Root = NewExprNode ();
+    Root->Left  = Expr;
+    Root->Op    = EXPR_BYTE0;
+
+    /* Return the result */
+    return Root;
 }
 
 
@@ -1065,7 +1079,7 @@ void FreeExpr (ExprNode* Root)
 ExprNode* ForceWordExpr (ExprNode* Expr)
 /* Force the given expression into a word and return the result. */
 {
-    /* And the expression by $FFFF to force it into word size */
+    /* AND the expression by $FFFF to force it into word size */
     ExprNode* Root = NewExprNode ();
     Root->Left  = Expr;
     Root->Op    = EXPR_AND;
@@ -1077,6 +1091,21 @@ ExprNode* ForceWordExpr (ExprNode* Expr)
 
 
 
+ExprNode* CompareExpr (ExprNode* Expr, long Val)
+/* Generate an expression that compares Expr and Val for equality */
+{
+    /* Generate a compare node */
+    ExprNode* Root = NewExprNode ();
+    Root->Left  = Expr;
+    Root->Op    = EXPR_EQ;
+    Root->Right        = LiteralExpr (Val);
+
+    /* Return the result */
+    return Root;
+}
+
+
+
 int IsConstExpr (ExprNode* Root)
 /* Return true if the given expression is a constant expression, that is, one
  * with no references to external symbols.
index b1ead1bc4b10c3ccc78f130f9ed6b07b0b12f153..7338b193e50a169e1bd3ae16298932ec2c2f3389 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (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       */
@@ -80,9 +80,15 @@ ExprNode* BranchExpr (unsigned Offs);
 ExprNode* ULabelExpr (unsigned Num);
 /* Return an expression for an unnamed label with the given index */
 
+ExprNode* ForceByteExpr (ExprNode* Expr);
+/* Force the given expression into a byte and return the result */
+
 ExprNode* ForceWordExpr (ExprNode* Expr);
 /* Force the given expression into a word and return the result. */
 
+ExprNode* CompareExpr (ExprNode* Expr, long Val);
+/* Generate an expression that compares Expr and Val for equality */
+
 int IsConstExpr (ExprNode* Root);
 /* Return true if the given expression is a constant expression, that is, one
  * with no references to external symbols.
index 6cd78b62ca37c0f157d6f8fd39bf4fd1db83b939..c39096aed47ca86ccc2bbee0c9817031e0771ec8 100644 (file)
 #include <ctype.h>
 
 /* common */
+#include "assertdefs.h"
 #include "bitops.h"
 #include "check.h"
 
 /* ca65 */
+#include "asserts.h"
 #include "ea.h"
 #include "error.h"
 #include "expr.h"
 #include "global.h"
+#include "instr.h"
 #include "nexttok.h"
 #include "objcode.h"
+#include "spool.h"
 #include "symtab.h"
-#include "instr.h"
 
 
 
@@ -65,6 +68,7 @@ static void PutPCRel16 (const InsDesc* Ins);
 static void PutBlockMove (const InsDesc* Ins);
 static void PutREP (const InsDesc* Ins);
 static void PutSEP (const InsDesc* Ins);
+static void PutJmp (const InsDesc* Ins);
 static void PutAll (const InsDesc* Ins);
 
 
@@ -89,7 +93,7 @@ static const struct {
        { "BPL", 0x0020000, 0x10, 0, PutPCRel8 },
        { "BRK", 0x0000001, 0x00, 0, PutAll },
        { "BVC", 0x0020000, 0x50, 0, PutPCRel8 },
-       { "BVS", 0x0020000, 0x70, 0, PutPCRel8 },
+       { "BVS", 0x0020000, 0x70, 0, PutPCRel8 },
        { "CLC", 0x0000001, 0x18, 0, PutAll },
        { "CLD", 0x0000001, 0xd8, 0, PutAll },
        { "CLI", 0x0000001, 0x58, 0, PutAll },
@@ -104,7 +108,7 @@ static const struct {
        { "INC", 0x000006c, 0x00, 4, PutAll },
        { "INX", 0x0000001, 0xe8, 0, PutAll },
        { "INY", 0x0000001, 0xc8, 0, PutAll },
-       { "JMP", 0x0000808, 0x4c, 6, PutAll },
+       { "JMP", 0x0000808, 0x4c, 6, PutJmp },
        { "JSR", 0x0000008, 0x20, 7, PutAll },
        { "LDA", 0x080A26C, 0xa0, 0, PutAll },
        { "LDX", 0x080030C, 0xa2, 1, PutAll },
@@ -132,7 +136,7 @@ static const struct {
        { "TSX", 0x0000001, 0xba, 0, PutAll },
        { "TXA", 0x0000001, 0x8a, 0, PutAll },
        { "TXS", 0x0000001, 0x9a, 0, PutAll },
-       { "TYA", 0x0000001, 0x98, 0, PutAll }
+       { "TYA", 0x0000001, 0x98, 0, PutAll }
     }
 };
 
@@ -175,7 +179,7 @@ static const struct {
        { "INX", 0x0000001, 0xe8, 0, PutAll },
        { "INY", 0x0000001, 0xc8, 0, PutAll },
        { "JMP", 0x0010808, 0x4c, 6, PutAll },
-       { "JSR", 0x0000008, 0x20, 7, PutAll },
+       { "JSR", 0x0000008, 0x20, 7, PutAll },
        { "LDA", 0x080A66C, 0xa0, 0, PutAll },
        { "LDX", 0x080030C, 0xa2, 1, PutAll },
        { "LDY", 0x080006C, 0xa0, 1, PutAll },
@@ -261,7 +265,7 @@ static const struct {
        { "JSL", 0x0000010, 0x20, 7, PutAll },
        { "JSR", 0x0010018, 0x20, 7, PutAll },
        { "LDA", 0x0b8f6fc, 0xa0, 0, PutAll },
-       { "LDX", 0x0c0030c, 0xa2, 1, PutAll },
+       { "LDX", 0x0c0030c, 0xa2, 1, PutAll },
        { "LDY", 0x0c0006c, 0xa0, 1, PutAll },
        { "LSR", 0x000006F, 0x42, 1, PutAll },
        { "MVN", 0x1000000, 0x54, 0, PutBlockMove },
@@ -304,7 +308,7 @@ static const struct {
        { "TAD", 0x0000001, 0x5b, 0, PutAll },   /* == TCD */
        { "TAS", 0x0000001, 0x1b, 0, PutAll },   /* == TCS */
        { "TAX", 0x0000001, 0xaa, 0, PutAll },
-       { "TAY", 0x0000001, 0xa8, 0, PutAll },
+       { "TAY", 0x0000001, 0xa8, 0, PutAll },
        { "TCD", 0x0000001, 0x5b, 0, PutAll },
        { "TCS", 0x0000001, 0x1b, 0, PutAll },
        { "TDA", 0x0000001, 0x7b, 0, PutAll },   /* == TDC */
@@ -437,62 +441,142 @@ unsigned char ExtBytes [AMI_COUNT] = {
 
 
 /*****************************************************************************/
-/*                            Handler functions                             */
+/*                            Handler functions                             */
 /*****************************************************************************/
 
 
 
-static long PutImmed8 (const InsDesc* Ins)
-/* Parse and emit an immediate 8 bit instruction. Return the value of the
- * operand if it's available and const.
+static int EvalEA (const InsDesc* Ins, EffAddr* A)
+/* Evaluate the effective address. All fields in A will be valid after calling
+ * this function. The function returns true on success and false on errors.
  */
 {
-    ExprNode* Expr;
-    ExprNode* Bank;
-    unsigned long AddrMode;
-    unsigned char OpCode;
-    long Val = -1;
-
-    /* Get the addressing mode used */
-    GetEA (&AddrMode, &Expr, &Bank);
+    /* Get the set of possible addressing modes */
+    GetEA (A);
 
     /* From the possible addressing modes, remove the ones that are invalid
      * for this instruction or CPU.
      */
-    AddrMode &= Ins->AddrMode;
+    A->AddrModeSet &= Ins->AddrMode;
 
     /* If we have possible zero page addressing modes, and the expression
      * involved (if any) is not in byte range, remove the zero page addressing
      * modes.
      */
-    if (Expr && (AddrMode & AM_ZP) && !IsByteExpr (Expr)) {
-       AddrMode &= ~AM_ZP;
+    if (A->Expr && (A->AddrModeSet & AM_ZP) && !IsByteExpr (A->Expr)) {
+               A->AddrModeSet &= ~AM_ZP;
     }
 
     /* Check if we have any adressing modes left */
-    if (AddrMode == 0) {
-       Error (ERR_ILLEGAL_ADDR_MODE);
-       return -1;
+    if (A->AddrModeSet == 0) {
+               Error (ERR_ILLEGAL_ADDR_MODE);
+               return 0;
+    }
+    A->AddrMode    = BitFind (A->AddrModeSet);
+    A->AddrModeBit = (0x01UL << A->AddrMode);
+
+    /* If the instruction has a one byte operand and immediate addressing is
+     * allowed but not used, check for an operand expression in the form
+     * <label or >label, where label is a far or absolute label. If found,
+     * 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)) &&
+        ExtBytes[A->AddrMode] == 1) {
+
+        /* Found, check the expression */
+        ExprNode* Left = A->Expr->Left;
+        if ((A->Expr->Op == EXPR_BYTE0 || A->Expr->Op == EXPR_BYTE1) &&
+            Left->Op == EXPR_SYMBOL                                &&
+            !SymIsZP (Left->V.Sym)) {
+
+            /* Output a warning */
+            Warning (WARN_SUSPICIOUS_ADDREXPR);
+        }
     }
-    AddrMode = BitFind (AddrMode);
 
     /* Build the opcode */
-    OpCode = Ins->BaseCode | EATab [Ins->ExtCode][AddrMode];
+    A->Opcode = Ins->BaseCode | EATab[Ins->ExtCode][A->AddrMode];
+
+    /* Success */
+    return 1;
+}
+
+
+
+static void EmitCode (EffAddr* A)
+/* Output code for the data in A */
+{
+    /* Check how many extension bytes are needed and output the instruction */
+    switch (ExtBytes[A->AddrMode]) {
+
+        case 0:
+           Emit0 (A->Opcode);
+           break;
+
+       case 1:
+           Emit1 (A->Opcode, A->Expr);
+           break;
+
+       case 2:
+           if (CPU == CPU_65816 && (A->AddrModeBit & (AM_ABS | AM_ABS_X | AM_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.
+                */
+                       Emit2 (A->Opcode, ForceWordExpr (A->Expr));
+           } else {
+               Emit2 (A->Opcode, A->Expr);
+           }
+           break;
+
+       case 3:
+           if (A->Bank) {
+               /* Separate bank given */
+               Emit3b (A->Opcode, A->Expr, A->Bank);
+           } else {
+               /* One far argument */
+               Emit3 (A->Opcode, A->Expr);
+           }
+           break;
+
+       default:
+           Internal ("Invalid operand byte count: %u", ExtBytes[A->AddrMode]);
+
+    }
+}
+
+
+
+static long PutImmed8 (const InsDesc* Ins)
+/* Parse and emit an immediate 8 bit instruction. Return the value of the
+ * operand if it's available and const.
+ */
+{
+    EffAddr A;
+    long Val = -1;
+
+    /* Evaluate the addressing mode */
+    if (EvalEA (Ins, &A) == 0) {
+        /* An error occurred */
+        return -1L;
+    }
 
     /* If we have an expression and it's const, get it's value */
-    if (Expr && IsConstExpr (Expr)) {
-       Val = GetExprVal (Expr);
+    if (A.Expr && IsConstExpr (A.Expr)) {
+       Val = GetExprVal (A.Expr);
     }
 
     /* Check how many extension bytes are needed and output the instruction */
-    switch (ExtBytes [AddrMode]) {
+    switch (ExtBytes[A.AddrMode]) {
 
-       case 1:
-           Emit1 (OpCode, Expr);
+       case 1:
+           Emit1 (A.Opcode, A.Expr);
            break;
 
        default:
-           Internal ("Invalid operand byte count: %u", ExtBytes [AddrMode]);
+           Internal ("Invalid operand byte count: %u", ExtBytes[A.AddrMode]);
     }
 
     /* Return the expression value */
@@ -543,12 +627,12 @@ static void PutREP (const InsDesc* Ins)
            Warning (WARN_CANNOT_TRACK_STATUS);
        } else {
            if (Val & 0x10) {
-               /* Index registers to 16 bit */
-               ExtBytes [AMI_IMM_INDEX] = 2;
+               /* Index registers to 16 bit */
+               ExtBytes[AMI_IMM_INDEX] = 2;
            }
            if (Val & 0x20) {
-               /* Accu to 16 bit */
-               ExtBytes [AMI_IMM_ACCU] = 2;
+               /* Accu to 16 bit */
+               ExtBytes[AMI_IMM_ACCU] = 2;
            }
        }
     }
@@ -584,100 +668,50 @@ static void PutSEP (const InsDesc* Ins)
 
 
 
-static void PutAll (const InsDesc* Ins)
-/* Handle all other instructions */
+static void PutJmp (const InsDesc* Ins)
+/* Handle the jump instruction for the 6502. Problem is that these chips have
+ * a bug: If the address crosses a page, the upper byte gets not corrected and
+ * the instruction will fail. The PutJmp function will add a linker assertion
+ * to check for this case and is otherwise identical to PutAll.
+ */
 {
-    ExprNode* Expr;
-    ExprNode* Bank;
-    unsigned long AddrModeSet;
-    unsigned char OpCode;
-    unsigned AddrMode;
-    unsigned long AddrModeBit;
-
-    /* Get the addressing mode used */
-    GetEA (&AddrModeSet, &Expr, &Bank);
-
-    /* From the possible addressing modes, remove the ones that are invalid
-     * for this instruction or CPU.
-     */
-    AddrModeSet &= Ins->AddrMode;
+    EffAddr A;
 
-    /* If we have possible zero page addressing modes, and the expression
-     * involved (if any) is not in byte range, remove the zero page addressing
-     * modes.
-     */
-    if (Expr && (AddrModeSet & AM_ZP) && !IsByteExpr (Expr)) {
-               AddrModeSet &= ~AM_ZP;
-    }
+    /* Evaluate the addressing mode used */
+    if (EvalEA (Ins, &A)) {
 
-    /* Check if we have any adressing modes left */
-    if (AddrModeSet == 0) {
-               Error (ERR_ILLEGAL_ADDR_MODE);
-               return;
-    }
-    AddrMode = BitFind (AddrModeSet);
+        /* Check for indirect addressing */
+        if (A.AddrModeBit & AM_ABS_IND) {
 
-    /* If the instruction has a one byte operand and immediate addressing is
-     * allowed but not used, check for an operand expression in the form
-     * <label or >label, where label is a far or absolute label. If found,
-     * emit a warning. This warning protects against a typo, where the '#'
-     * for the immediate operand is omitted.
-     */
-    if (Expr && (Ins->AddrMode & AM_IMM)                &&
-        (AddrModeSet & (AM_DIR | AM_ABS | AM_ABS_LONG)) &&
-        ExtBytes[AddrMode] == 1) {
+            /* 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
+             * things will go weird later.
+             */
+            ExprNode* E = CompareExpr (ForceByteExpr (CloneExpr (A.Expr)), 0xFF);
 
-        /* Found, check the expression */
-        ExprNode* Left = Expr->Left;
-        if ((Expr->Op == EXPR_BYTE0 || Expr->Op == EXPR_BYTE1) &&
-            Left->Op == EXPR_SYMBOL                            &&
-            !SymIsZP (Left->V.Sym)) {
+            /* Generate the message */
+            unsigned Msg = GetStringId ("\"jmp (abs)\" across page border");
 
-            /* Output a warning */
-            Warning (WARN_SUSPICIOUS_ADDREXPR);
+            /* Generate the assertion */
+            AddAssertion (E, ASSERT_ACT_WARN, Msg);
         }
-    }
-
-    /* Build the opcode */
-    OpCode = Ins->BaseCode | EATab [Ins->ExtCode][AddrMode];
 
-    /* Check how many extension bytes are needed and output the instruction */
-    switch (ExtBytes[AddrMode]) {
+        /* No error, output code */
+        EmitCode (&A);
+    }
+}
 
-        case 0:
-           Emit0 (OpCode);
-           break;
-
-       case 1:
-           Emit1 (OpCode, Expr);
-           break;
-
-       case 2:
-           AddrModeBit = (1L << AddrMode);
-           if (CPU == CPU_65816 && (AddrModeBit & (AM_ABS | AM_ABS_X | AM_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.
-                */
-                       Emit2 (OpCode, ForceWordExpr (Expr));
-           } else {
-               Emit2 (OpCode, Expr);
-           }
-           break;
 
-       case 3:
-           if (Bank) {
-               /* Separate bank given */
-               Emit3b (OpCode, Expr, Bank);
-           } else {
-               /* One far argument */
-               Emit3 (OpCode, Expr);
-           }
-           break;
 
-       default:
-           Internal ("Invalid operand byte count: %u", ExtBytes [AddrMode]);
+static void PutAll (const InsDesc* Ins)
+/* Handle all other instructions */
+{
+    EffAddr A;
 
+    /* Evaluate the addressing mode used */
+    if (EvalEA (Ins, &A)) {
+        /* No error, output code */
+        EmitCode (&A);
     }
 }
 
index 31dfef06951f3c69c0bcf87583f1b27b2e677591..1b0bdfff1b7c7ee0c431ef4dbfd5ea564bf7cd23 100644 (file)
@@ -48,6 +48,7 @@
 
 /* ca65 */
 #include "abend.h"
+#include "asserts.h"
 #include "error.h"
 #include "expr.h"
 #include "feature.h"
@@ -56,7 +57,6 @@
 #include "incpath.h"
 #include "instr.h"
 #include "istack.h"
-#include "ldassert.h"
 #include "lineinfo.h"
 #include "listing.h"
 #include "macro.h"
index 12efb6503afda8b71f13bfa67990602f26418d2a..424f5476aa936a7ca7be7420e4027f08756aa3c0 100644 (file)
@@ -10,7 +10,8 @@ CC    = gcc
 EBIND  = emxbind
 LDFLAGS        =
 
-OBJS =  condasm.o      \
+OBJS =  asserts.o       \
+        condasm.o      \
        dbginfo.o       \
        ea.o            \
         error.o                \
@@ -22,7 +23,6 @@ OBJS =  condasm.o     \
        incpath.o       \
         instr.o                \
        istack.o        \
-        ldassert.o      \
        lineinfo.o      \
        listing.o       \
        macpack.o       \
index ac2ca050ef24ecf16d3b12f75488c53759702e08..82f85bde5086f72b857e9a482b1297ce143e1897 100644 (file)
@@ -43,7 +43,8 @@ CFLAGS  += -i=..\common
 # ------------------------------------------------------------------------------
 # All library OBJ files
 
-OBJS =         condasm.obj     \
+OBJS =         asserts.obj     \
+        condasm.obj    \
        dbginfo.obj     \
        ea.obj          \
        error.obj       \
@@ -55,7 +56,6 @@ OBJS =        condasm.obj     \
        incpath.obj     \
                instr.obj       \
        istack.obj      \
-        ldassert.obj    \
        lineinfo.obj    \
        listing.obj     \
        macpack.obj     \
index 407cf5e7fdd6332b0dc58e8b2b2ae5a7dc1dc893..2660ef8f4bdce1730427f803a4aeeedcfa87edd4 100644 (file)
@@ -39,7 +39,8 @@
 #include <ctype.h>
 #include <errno.h>
 
-/* common */
+/* common */     
+#include "assertdefs.h"
 #include "bitops.h"
 #include "cddefs.h"
 #include "coll.h"
@@ -48,6 +49,7 @@
 #include "xmalloc.h"
 
 /* ca65 */
+#include "asserts.h"
 #include "condasm.h"
 #include "dbginfo.h"
 #include "error.h"
@@ -56,7 +58,6 @@
 #include "global.h"
 #include "incpath.h"
 #include "instr.h"
-#include "ldassert.h"
 #include "listing.h"
 #include "macpack.h"
 #include "macro.h"
@@ -354,10 +355,12 @@ static void DoAssert (void)
         case 0:
         case 1:
             /* Warning */
+            Action = ASSERT_ACT_WARN;
             break;
 
         case 2:
             /* Error */
+            Action = ASSERT_ACT_ERROR;
             break;
 
         default:
diff --git a/src/common/assertdefs.h b/src/common/assertdefs.h
new file mode 100644 (file)
index 0000000..d992f5a
--- /dev/null
@@ -0,0 +1,58 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                               assertdefs.h                               */
+/*                                                                           */
+/*                     Definitions for linker assertions                     */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 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 ASSERTDEFS_H
+#define ASSERTDEFS_H
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* Assertion actions */
+#define ASSERT_ACT_WARN         0x00    /* Print a warning */
+#define ASSERT_ACT_ERROR        0x01    /* Print an error (no output) */
+
+
+
+/* End of assertdefs.h */
+
+#endif
+
+
+