Completed assertions, add auto assertion for jmp (abs) bug
git-svn-id: svn://svn.cc65.org/cc65/trunk@2203 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
137
src/ca65/asserts.c
Normal file
137
src/ca65/asserts.c
Normal file
@@ -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 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
71
src/ca65/asserts.h
Normal file
71
src/ca65/asserts.h
Normal file
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -7,9 +7,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<EFBFBD>merstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ld65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
@@ -47,52 +48,52 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
|
void GetEA (EffAddr* A)
|
||||||
/* Parse an effective address, return the possible modes in AddrMode, and the
|
/* Parse an effective address, return the result in A */
|
||||||
* expression involved (if any) in Expr.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
/* Clear the expressions */
|
/* Clear the output struct */
|
||||||
*Bank = *Expr = 0;
|
A->AddrModeSet = 0;
|
||||||
|
A->Bank = 0;
|
||||||
|
A->Expr = 0;
|
||||||
|
|
||||||
|
|
||||||
if (TokIsSep (Tok)) {
|
if (TokIsSep (Tok)) {
|
||||||
|
|
||||||
*AddrMode = AM_IMPLICIT;
|
A->AddrModeSet = AM_IMPLICIT;
|
||||||
|
|
||||||
} else if (Tok == TOK_HASH) {
|
} else if (Tok == TOK_HASH) {
|
||||||
|
|
||||||
/* #val */
|
/* #val */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
*Expr = Expression ();
|
A->Expr = Expression ();
|
||||||
*AddrMode = AM_IMM;
|
A->AddrModeSet = AM_IMM;
|
||||||
|
|
||||||
} else if (Tok == TOK_A) {
|
} else if (Tok == TOK_A) {
|
||||||
|
|
||||||
NextTok ();
|
NextTok ();
|
||||||
*AddrMode = AM_ACCU;
|
A->AddrModeSet = AM_ACCU;
|
||||||
|
|
||||||
} else if (Tok == TOK_LBRACK) {
|
} else if (Tok == TOK_LBRACK) {
|
||||||
|
|
||||||
/* [dir] or [dir],y */
|
/* [dir] or [dir],y */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
*Expr = Expression ();
|
A->Expr = Expression ();
|
||||||
Consume (TOK_RBRACK, ERR_RBRACK_EXPECTED);
|
Consume (TOK_RBRACK, ERR_RBRACK_EXPECTED);
|
||||||
if (Tok == TOK_COMMA) {
|
if (Tok == TOK_COMMA) {
|
||||||
/* [dir],y */
|
/* [dir],y */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
Consume (TOK_Y, ERR_Y_EXPECTED);
|
Consume (TOK_Y, ERR_Y_EXPECTED);
|
||||||
*AddrMode = AM_DIR_IND_LONG_Y;
|
A->AddrModeSet = AM_DIR_IND_LONG_Y;
|
||||||
} else {
|
} else {
|
||||||
/* [dir] */
|
/* [dir] */
|
||||||
*AddrMode = AM_DIR_IND_LONG;
|
A->AddrModeSet = AM_DIR_IND_LONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (Tok == TOK_LPAREN) {
|
} else if (Tok == TOK_LPAREN) {
|
||||||
|
|
||||||
/* One of the indirect modes */
|
/* One of the indirect modes */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
*Expr = Expression ();
|
A->Expr = Expression ();
|
||||||
|
|
||||||
if (Tok == TOK_COMMA) {
|
if (Tok == TOK_COMMA) {
|
||||||
|
|
||||||
@@ -101,12 +102,12 @@ void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
|
|||||||
if (Tok == TOK_X) {
|
if (Tok == TOK_X) {
|
||||||
/* (adr,x) */
|
/* (adr,x) */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
*AddrMode = AM_ABS_X_IND | AM_DIR_X_IND;
|
A->AddrModeSet = AM_ABS_X_IND | AM_DIR_X_IND;
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
} else if (Tok == TOK_S) {
|
} else if (Tok == TOK_S) {
|
||||||
/* (rel,s),y */
|
/* (rel,s),y */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
*AddrMode = AM_STACK_REL_IND_Y;
|
A->AddrModeSet = AM_STACK_REL_IND_Y;
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
Consume (TOK_Y, ERR_Y_EXPECTED);
|
Consume (TOK_Y, ERR_Y_EXPECTED);
|
||||||
@@ -122,10 +123,10 @@ void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
|
|||||||
/* (adr),y */
|
/* (adr),y */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
Consume (TOK_Y, ERR_Y_EXPECTED);
|
Consume (TOK_Y, ERR_Y_EXPECTED);
|
||||||
*AddrMode = AM_DIR_IND_Y;
|
A->AddrModeSet = AM_DIR_IND_Y;
|
||||||
} else {
|
} else {
|
||||||
/* (adr) */
|
/* (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,y
|
||||||
* adr,s
|
* adr,s
|
||||||
*/
|
*/
|
||||||
*Expr = Expression ();
|
A->Expr = Expression ();
|
||||||
|
|
||||||
if (Tok == TOK_DOT) {
|
if (Tok == TOK_DOT) {
|
||||||
|
|
||||||
/* Expr was a bank specification: bank.adr or bank.adr,x */
|
/* Expr was a bank specification: bank.adr or bank.adr,x */
|
||||||
*Bank = *Expr;
|
A->Bank = A->Expr;
|
||||||
NextTok ();
|
NextTok ();
|
||||||
*Expr = Expression ();
|
A->Expr = Expression ();
|
||||||
if (Tok == TOK_COMMA) {
|
if (Tok == TOK_COMMA) {
|
||||||
/* bank.adr,x */
|
/* bank.adr,x */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
Consume (TOK_X, ERR_X_EXPECTED);
|
Consume (TOK_X, ERR_X_EXPECTED);
|
||||||
*AddrMode = AM_ABS_LONG_X;
|
A->AddrModeSet = AM_ABS_LONG_X;
|
||||||
} else {
|
} else {
|
||||||
/* bank.adr */
|
/* bank.adr */
|
||||||
*AddrMode = AM_ABS_LONG;
|
A->AddrModeSet = AM_ABS_LONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -166,17 +167,17 @@ void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
|
|||||||
switch (Tok) {
|
switch (Tok) {
|
||||||
|
|
||||||
case TOK_X:
|
case TOK_X:
|
||||||
*AddrMode = AM_ABS_X | AM_DIR_X;
|
A->AddrModeSet = AM_ABS_X | AM_DIR_X;
|
||||||
NextTok ();
|
NextTok ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_Y:
|
case TOK_Y:
|
||||||
*AddrMode = AM_ABS_Y | AM_DIR_Y;
|
A->AddrModeSet = AM_ABS_Y | AM_DIR_Y;
|
||||||
NextTok ();
|
NextTok ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_S:
|
case TOK_S:
|
||||||
*AddrMode = AM_STACK_REL;
|
A->AddrModeSet = AM_STACK_REL;
|
||||||
NextTok ();
|
NextTok ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -187,7 +188,7 @@ void GetEA (unsigned long* AddrMode, ExprNode** Expr, ExprNode** Bank)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
*AddrMode = AM_ABS | AM_DIR;
|
A->AddrModeSet = AM_ABS | AM_DIR;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<>merstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -38,26 +38,36 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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);
|
void GetEA (EffAddr* A);
|
||||||
/* Parse an effective address, return the possible modes in AddrMode, and the
|
/* Parse an effective address, return the result in A */
|
||||||
* expression involved (if any) in Expr.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<EFBFBD>merstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* 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)
|
ExprNode* LiteralExpr (long Val)
|
||||||
/* Return an expression tree that encodes the given literal value */
|
/* Return an expression tree that encodes the given literal value */
|
||||||
{
|
{
|
||||||
@@ -1050,14 +1062,16 @@ ExprNode* ULabelExpr (unsigned Num)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FreeExpr (ExprNode* Root)
|
ExprNode* ForceByteExpr (ExprNode* Expr)
|
||||||
/* Free the expression, Root is pointing to. */
|
/* Force the given expression into a byte and return the result */
|
||||||
{
|
{
|
||||||
if (Root) {
|
/* Use the low byte operator to force the expression into byte size */
|
||||||
FreeExpr (Root->Left);
|
ExprNode* Root = NewExprNode ();
|
||||||
FreeExpr (Root->Right);
|
Root->Left = Expr;
|
||||||
FreeExprNode (Root);
|
Root->Op = EXPR_BYTE0;
|
||||||
}
|
|
||||||
|
/* Return the result */
|
||||||
|
return Root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1065,7 +1079,7 @@ void FreeExpr (ExprNode* Root)
|
|||||||
ExprNode* ForceWordExpr (ExprNode* Expr)
|
ExprNode* ForceWordExpr (ExprNode* Expr)
|
||||||
/* Force the given expression into a word and return the result. */
|
/* 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 ();
|
ExprNode* Root = NewExprNode ();
|
||||||
Root->Left = Expr;
|
Root->Left = Expr;
|
||||||
Root->Op = EXPR_AND;
|
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)
|
int IsConstExpr (ExprNode* Root)
|
||||||
/* Return true if the given expression is a constant expression, that is, one
|
/* Return true if the given expression is a constant expression, that is, one
|
||||||
* with no references to external symbols.
|
* with no references to external symbols.
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<>merstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -80,9 +80,15 @@ ExprNode* BranchExpr (unsigned Offs);
|
|||||||
ExprNode* ULabelExpr (unsigned Num);
|
ExprNode* ULabelExpr (unsigned Num);
|
||||||
/* Return an expression for an unnamed label with the given index */
|
/* 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);
|
ExprNode* ForceWordExpr (ExprNode* Expr);
|
||||||
/* Force the given expression into a word and return the result. */
|
/* 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);
|
int IsConstExpr (ExprNode* Root);
|
||||||
/* Return true if the given expression is a constant expression, that is, one
|
/* Return true if the given expression is a constant expression, that is, one
|
||||||
* with no references to external symbols.
|
* with no references to external symbols.
|
||||||
|
|||||||
266
src/ca65/instr.c
266
src/ca65/instr.c
@@ -38,18 +38,21 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "assertdefs.h"
|
||||||
#include "bitops.h"
|
#include "bitops.h"
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
|
#include "asserts.h"
|
||||||
#include "ea.h"
|
#include "ea.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "instr.h"
|
||||||
#include "nexttok.h"
|
#include "nexttok.h"
|
||||||
#include "objcode.h"
|
#include "objcode.h"
|
||||||
|
#include "spool.h"
|
||||||
#include "symtab.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 PutBlockMove (const InsDesc* Ins);
|
||||||
static void PutREP (const InsDesc* Ins);
|
static void PutREP (const InsDesc* Ins);
|
||||||
static void PutSEP (const InsDesc* Ins);
|
static void PutSEP (const InsDesc* Ins);
|
||||||
|
static void PutJmp (const InsDesc* Ins);
|
||||||
static void PutAll (const InsDesc* Ins);
|
static void PutAll (const InsDesc* Ins);
|
||||||
|
|
||||||
|
|
||||||
@@ -104,7 +108,7 @@ static const struct {
|
|||||||
{ "INC", 0x000006c, 0x00, 4, PutAll },
|
{ "INC", 0x000006c, 0x00, 4, PutAll },
|
||||||
{ "INX", 0x0000001, 0xe8, 0, PutAll },
|
{ "INX", 0x0000001, 0xe8, 0, PutAll },
|
||||||
{ "INY", 0x0000001, 0xc8, 0, PutAll },
|
{ "INY", 0x0000001, 0xc8, 0, PutAll },
|
||||||
{ "JMP", 0x0000808, 0x4c, 6, PutAll },
|
{ "JMP", 0x0000808, 0x4c, 6, PutJmp },
|
||||||
{ "JSR", 0x0000008, 0x20, 7, PutAll },
|
{ "JSR", 0x0000008, 0x20, 7, PutAll },
|
||||||
{ "LDA", 0x080A26C, 0xa0, 0, PutAll },
|
{ "LDA", 0x080A26C, 0xa0, 0, PutAll },
|
||||||
{ "LDX", 0x080030C, 0xa2, 1, PutAll },
|
{ "LDX", 0x080030C, 0xa2, 1, PutAll },
|
||||||
@@ -442,57 +446,137 @@ unsigned char ExtBytes [AMI_COUNT] = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static long PutImmed8 (const InsDesc* Ins)
|
static int EvalEA (const InsDesc* Ins, EffAddr* A)
|
||||||
/* Parse and emit an immediate 8 bit instruction. Return the value of the
|
/* Evaluate the effective address. All fields in A will be valid after calling
|
||||||
* operand if it's available and const.
|
* this function. The function returns true on success and false on errors.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ExprNode* Expr;
|
/* Get the set of possible addressing modes */
|
||||||
ExprNode* Bank;
|
GetEA (A);
|
||||||
unsigned long AddrMode;
|
|
||||||
unsigned char OpCode;
|
|
||||||
long Val = -1;
|
|
||||||
|
|
||||||
/* Get the addressing mode used */
|
|
||||||
GetEA (&AddrMode, &Expr, &Bank);
|
|
||||||
|
|
||||||
/* From the possible addressing modes, remove the ones that are invalid
|
/* From the possible addressing modes, remove the ones that are invalid
|
||||||
* for this instruction or CPU.
|
* for this instruction or CPU.
|
||||||
*/
|
*/
|
||||||
AddrMode &= Ins->AddrMode;
|
A->AddrModeSet &= Ins->AddrMode;
|
||||||
|
|
||||||
/* If we have possible zero page addressing modes, and the expression
|
/* If we have possible zero page addressing modes, and the expression
|
||||||
* involved (if any) is not in byte range, remove the zero page addressing
|
* involved (if any) is not in byte range, remove the zero page addressing
|
||||||
* modes.
|
* modes.
|
||||||
*/
|
*/
|
||||||
if (Expr && (AddrMode & AM_ZP) && !IsByteExpr (Expr)) {
|
if (A->Expr && (A->AddrModeSet & AM_ZP) && !IsByteExpr (A->Expr)) {
|
||||||
AddrMode &= ~AM_ZP;
|
A->AddrModeSet &= ~AM_ZP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have any adressing modes left */
|
/* Check if we have any adressing modes left */
|
||||||
if (AddrMode == 0) {
|
if (A->AddrModeSet == 0) {
|
||||||
Error (ERR_ILLEGAL_ADDR_MODE);
|
Error (ERR_ILLEGAL_ADDR_MODE);
|
||||||
return -1;
|
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 */
|
/* Build the opcode */
|
||||||
OpCode = Ins->BaseCode | EATab [Ins->ExtCode][AddrMode];
|
A->Opcode = Ins->BaseCode | EATab[Ins->ExtCode][A->AddrMode];
|
||||||
|
|
||||||
/* If we have an expression and it's const, get it's value */
|
/* Success */
|
||||||
if (Expr && IsConstExpr (Expr)) {
|
return 1;
|
||||||
Val = GetExprVal (Expr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void EmitCode (EffAddr* A)
|
||||||
|
/* Output code for the data in A */
|
||||||
|
{
|
||||||
/* Check how many extension bytes are needed and output the instruction */
|
/* Check how many extension bytes are needed and output the instruction */
|
||||||
switch (ExtBytes [AddrMode]) {
|
switch (ExtBytes[A->AddrMode]) {
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
Emit0 (A->Opcode);
|
||||||
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
Emit1 (OpCode, Expr);
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Invalid operand byte count: %u", ExtBytes [AddrMode]);
|
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 (A.Expr && IsConstExpr (A.Expr)) {
|
||||||
|
Val = GetExprVal (A.Expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check how many extension bytes are needed and output the instruction */
|
||||||
|
switch (ExtBytes[A.AddrMode]) {
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
Emit1 (A.Opcode, A.Expr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Internal ("Invalid operand byte count: %u", ExtBytes[A.AddrMode]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the expression value */
|
/* Return the expression value */
|
||||||
@@ -584,100 +668,50 @@ static void PutSEP (const InsDesc* Ins)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
EffAddr A;
|
||||||
|
|
||||||
|
/* Evaluate the addressing mode used */
|
||||||
|
if (EvalEA (Ins, &A)) {
|
||||||
|
|
||||||
|
/* Check for indirect addressing */
|
||||||
|
if (A.AddrModeBit & AM_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
|
||||||
|
* things will go weird later.
|
||||||
|
*/
|
||||||
|
ExprNode* E = CompareExpr (ForceByteExpr (CloneExpr (A.Expr)), 0xFF);
|
||||||
|
|
||||||
|
/* Generate the message */
|
||||||
|
unsigned Msg = GetStringId ("\"jmp (abs)\" across page border");
|
||||||
|
|
||||||
|
/* Generate the assertion */
|
||||||
|
AddAssertion (E, ASSERT_ACT_WARN, Msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No error, output code */
|
||||||
|
EmitCode (&A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void PutAll (const InsDesc* Ins)
|
static void PutAll (const InsDesc* Ins)
|
||||||
/* Handle all other instructions */
|
/* Handle all other instructions */
|
||||||
{
|
{
|
||||||
ExprNode* Expr;
|
EffAddr A;
|
||||||
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;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if we have any adressing modes left */
|
|
||||||
if (AddrModeSet == 0) {
|
|
||||||
Error (ERR_ILLEGAL_ADDR_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
AddrMode = BitFind (AddrModeSet);
|
|
||||||
|
|
||||||
/* 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) {
|
|
||||||
|
|
||||||
/* 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)) {
|
|
||||||
|
|
||||||
/* Output a warning */
|
|
||||||
Warning (WARN_SUSPICIOUS_ADDREXPR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the opcode */
|
|
||||||
OpCode = Ins->BaseCode | EATab [Ins->ExtCode][AddrMode];
|
|
||||||
|
|
||||||
/* Check how many extension bytes are needed and output the instruction */
|
|
||||||
switch (ExtBytes[AddrMode]) {
|
|
||||||
|
|
||||||
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]);
|
|
||||||
|
|
||||||
|
/* Evaluate the addressing mode used */
|
||||||
|
if (EvalEA (Ins, &A)) {
|
||||||
|
/* No error, output code */
|
||||||
|
EmitCode (&A);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "abend.h"
|
#include "abend.h"
|
||||||
|
#include "asserts.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "feature.h"
|
#include "feature.h"
|
||||||
@@ -56,7 +57,6 @@
|
|||||||
#include "incpath.h"
|
#include "incpath.h"
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
#include "istack.h"
|
#include "istack.h"
|
||||||
#include "ldassert.h"
|
|
||||||
#include "lineinfo.h"
|
#include "lineinfo.h"
|
||||||
#include "listing.h"
|
#include "listing.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ CC = gcc
|
|||||||
EBIND = emxbind
|
EBIND = emxbind
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
OBJS = condasm.o \
|
OBJS = asserts.o \
|
||||||
|
condasm.o \
|
||||||
dbginfo.o \
|
dbginfo.o \
|
||||||
ea.o \
|
ea.o \
|
||||||
error.o \
|
error.o \
|
||||||
@@ -22,7 +23,6 @@ OBJS = condasm.o \
|
|||||||
incpath.o \
|
incpath.o \
|
||||||
instr.o \
|
instr.o \
|
||||||
istack.o \
|
istack.o \
|
||||||
ldassert.o \
|
|
||||||
lineinfo.o \
|
lineinfo.o \
|
||||||
listing.o \
|
listing.o \
|
||||||
macpack.o \
|
macpack.o \
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ CFLAGS += -i=..\common
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# All library OBJ files
|
# All library OBJ files
|
||||||
|
|
||||||
OBJS = condasm.obj \
|
OBJS = asserts.obj \
|
||||||
|
condasm.obj \
|
||||||
dbginfo.obj \
|
dbginfo.obj \
|
||||||
ea.obj \
|
ea.obj \
|
||||||
error.obj \
|
error.obj \
|
||||||
@@ -55,7 +56,6 @@ OBJS = condasm.obj \
|
|||||||
incpath.obj \
|
incpath.obj \
|
||||||
instr.obj \
|
instr.obj \
|
||||||
istack.obj \
|
istack.obj \
|
||||||
ldassert.obj \
|
|
||||||
lineinfo.obj \
|
lineinfo.obj \
|
||||||
listing.obj \
|
listing.obj \
|
||||||
macpack.obj \
|
macpack.obj \
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "assertdefs.h"
|
||||||
#include "bitops.h"
|
#include "bitops.h"
|
||||||
#include "cddefs.h"
|
#include "cddefs.h"
|
||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
|
#include "asserts.h"
|
||||||
#include "condasm.h"
|
#include "condasm.h"
|
||||||
#include "dbginfo.h"
|
#include "dbginfo.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
@@ -56,7 +58,6 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "incpath.h"
|
#include "incpath.h"
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
#include "ldassert.h"
|
|
||||||
#include "listing.h"
|
#include "listing.h"
|
||||||
#include "macpack.h"
|
#include "macpack.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
@@ -354,10 +355,12 @@ static void DoAssert (void)
|
|||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
/* Warning */
|
/* Warning */
|
||||||
|
Action = ASSERT_ACT_WARN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
/* Error */
|
/* Error */
|
||||||
|
Action = ASSERT_ACT_ERROR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
58
src/common/assertdefs.h
Normal file
58
src/common/assertdefs.h
Normal file
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user