]> git.sur5r.net Git - cc65/commitdiff
Working on the backend
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 30 Apr 2001 20:00:13 +0000 (20:00 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 30 Apr 2001 20:00:13 +0000 (20:00 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@699 b7a2c559-68d2-44c3-8de9-860c34a00d81

12 files changed:
src/cc65/codeent.c [new file with mode: 0644]
src/cc65/codeent.h [new file with mode: 0644]
src/cc65/codeinfo.h [new file with mode: 0644]
src/cc65/codelab.c [new file with mode: 0644]
src/cc65/codelab.h [new file with mode: 0644]
src/cc65/codeseg.c [new file with mode: 0644]
src/cc65/codeseg.h [new file with mode: 0644]
src/cc65/dataseg.c [new file with mode: 0644]
src/cc65/dataseg.h [new file with mode: 0644]
src/cc65/make/gcc.mak
src/cc65/opcodes.c [new file with mode: 0644]
src/cc65/opcodes.h [new file with mode: 0644]

diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c
new file mode 100644 (file)
index 0000000..711ecf1
--- /dev/null
@@ -0,0 +1,170 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                codeent.c                                 */
+/*                                                                           */
+/*                           Code segment entry                             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 "xmalloc.h"
+
+/* b6502 */
+#include "error.h"
+#include "label.h"
+#include "opcodes.h"
+#include "codeent.h"
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+CodeEntry* NewCodeEntry (const OPCDesc* D, am_t AM)
+/* Create a new code entry, initialize and return it */
+{
+    /* Allocate memory */
+    CodeEntry* E = xmalloc (sizeof (CodeEntry));
+
+    /* Initialize the fields */
+    E->OPC     = D->OPC;
+    E->AM      = AM;
+    E->Size    = GetInsnSize (E->OPC, E->AM);
+    E->Hints   = 0;
+    E->Arg.Num = 0;
+    E->Flags   = 0;
+    E->Usage   = D->Usage;
+    E->JumpTo  = 0;
+    InitCollection (&E->Labels);
+
+    /* Return the initialized struct */
+    return E;
+}
+
+
+
+void FreeCodeEntry (CodeEntry* E)
+/* Free the given code entry */
+{
+    /* ## Free the string argument if we have one */
+
+    /* Cleanup the collection */
+    DoneCollection (&E->Labels);
+
+    /* Free the entry */
+    xfree (E);
+}
+
+
+
+void OutputCodeEntry (FILE* F, const CodeEntry* E)
+/* Output the code entry to a file */
+{
+    const OPCDesc* D;
+
+    /* If we have a label, print that */
+    unsigned LabelCount = CollCount (&E->Labels);
+    unsigned I;
+    for (I = 0; I < LabelCount; ++I) {
+       OutputCodeLabel (F, CollConstAt (&E->Labels, I));
+    }
+
+    /* Get the opcode description */
+    D = GetOPCDesc (E->OPC);
+
+    /* Print the mnemonic */
+    fprintf (F, "\t%s", D->Mnemo);
+
+    /* Print the operand */
+    switch (E->AM) {
+
+       case AM_IMP:
+           /* implicit + accumulator */
+           break;
+
+       case AM_IMM:
+           /* immidiate */
+           fprintf (F, "\t#%s", E->Arg.Expr);
+           break;
+
+       case AM_ZP:
+       case AM_ABS:
+       case AM_BRA:
+           /* zeropage, absolute and branch */
+           fprintf (F, "\t%s", E->Arg.Expr);
+           break;
+
+       case AM_ZPX:
+       case AM_ABSX:
+           /* zeropage,X and absolute,X */
+           fprintf (F, "\t%s,x", E->Arg.Expr);
+           break;
+
+       case AM_ABSY:
+           /* absolute,Y */
+           fprintf (F, "\t%s,y", E->Arg.Expr);
+           break;
+
+       case AM_ZPX_IND:
+           /* (zeropage,x) */
+                   fprintf (F, "\t(%s,x)", E->Arg.Expr);
+           break;
+
+       case AM_ZP_INDY:
+           /* (zeropage),y */
+                   fprintf (F, "\t(%s),y", E->Arg.Expr);
+           break;
+
+       case AM_ZP_IND:
+           /* (zeropage) */
+                   fprintf (F, "\t(%s)", E->Arg.Expr);
+           break;
+
+       default:
+           Internal ("Invalid addressing mode");
+
+    }
+
+    /* Terminate the line */
+    fprintf (F, "\n");
+}
+
+
+
+
diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h
new file mode 100644 (file)
index 0000000..f627c90
--- /dev/null
@@ -0,0 +1,98 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                codeent.h                                 */
+/*                                                                           */
+/*                           Code segment entry                             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 CODEENT_H
+#define CODEENT_H
+
+
+
+#include <stdio.h>
+
+/* common */
+#include "coll.h"
+
+/* b6502 */
+#include "label.h"
+#include "opcodes.h"
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+/* Code entry structure */
+typedef struct CodeEntry CodeEntry;
+struct CodeEntry {
+    opc_t              OPC;            /* Opcode */
+    am_t               AM;             /* Adressing mode */
+    unsigned char      Size;           /* Estimated size */
+    unsigned char      Hints;          /* Hints for this entry */
+    union {
+       unsigned        Num;            /* Numeric argument */
+       char*           Expr;           /* Textual argument */
+    } Arg;
+    unsigned short     Flags;          /* Flags */
+    unsigned short     Usage;          /* Register usage for this entry */
+    CodeLabel*         JumpTo;         /* Jump label */
+    Collection         Labels;         /* Labels for this instruction */
+};
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+CodeEntry* NewCodeEntry (const OPCDesc* D, am_t AM);
+/* Create a new code entry, initialize and return it */
+
+void FreeCodeEntry (CodeEntry* E);
+/* Free the given code entry */
+
+void OutputCodeEntry (FILE* F, const CodeEntry* E);
+/* Output the code entry to a file */
+
+
+
+/* End of codeent.h */
+#endif
+
+
+
diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h
new file mode 100644 (file)
index 0000000..49ba670
--- /dev/null
@@ -0,0 +1,80 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                               codeinfo.h                                 */
+/*                                                                           */
+/*             Additional information about code instructions               */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 CODEINFO_H
+#define CODEINFO_H
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+/* Flags that tell what a specific instruction does with a register.
+ * Please note that *changing* a register must not necessarily mean that the
+ * value currently in the register is used. A prominent example is a load
+ * instruction: It changes the register contents and does not use the old
+ * value. On the flip side, a shift or something similar would use the
+ * current value and change it.
+ */
+#define CI_USE_NONE    0x0000U         /* Use nothing */
+#define CI_USE_A       0x0001U         /* Use the A register */
+#define CI_USE_X       0x0002U         /* Use the X register */
+#define CI_USE_Y       0x0004U         /* Use the Y register */
+#define CI_MASK_USE    0x00FFU         /* Extract usage info */
+
+#define CI_CHG_NONE    0x0000U         /* Change nothing */
+#define CI_CHG_A       0x0100U         /* Change the A register */
+#define CI_CHG_X       0x0200U         /* Change the X register */
+#define CI_CHG_Y       0x0400U         /* Change the Y register */
+#define CI_MASK_CHG    0xFF00U         /* Extract change info */
+
+#define CI_NONE                0x0000U         /* Nothing used/changed */
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+/* End of codeinfo.h */
+#endif
+
+
+
diff --git a/src/cc65/codelab.c b/src/cc65/codelab.c
new file mode 100644 (file)
index 0000000..823f2eb
--- /dev/null
@@ -0,0 +1,91 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 label.c                                  */
+/*                                                                           */
+/*                          Code label structure                            */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 "xmalloc.h"
+
+/* cc65 */
+#include "label.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+CodeLabel* NewCodeLabel (const char* Name, unsigned Hash)
+/* Create a new code label, initialize and return it */
+{
+    /* Allocate memory */
+    CodeLabel* L = xmalloc (sizeof (CodeLabel));
+
+    /* Initialize the fields */
+    L->Next  = 0;
+    L->Name  = xstrdup (Name);
+    L->Hash  = Hash;
+    L->Owner = 0;
+    InitCollection (&L->JumpFrom);
+
+    /* Return the new label */
+    return L;
+}
+
+
+
+void FreeCodeLabel (CodeLabel* L)
+/* Free the given code label */
+{
+    /* Free the name */
+    xfree (L->Name);
+
+    /* Free the collection */
+    DoneCollection (&L->JumpFrom);
+
+    /* Delete the struct */
+    xfree (L);
+}
+
+
+
+void OutputCodeLabel (FILE* F, const CodeLabel* L)
+/* Output the code label to a file */
+{
+    fprintf (F, "%s:\n", L->Name);
+}
+
+
+
diff --git a/src/cc65/codelab.h b/src/cc65/codelab.h
new file mode 100644 (file)
index 0000000..8fb3143
--- /dev/null
@@ -0,0 +1,87 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 label.h                                  */
+/*                                                                           */
+/*                          Code label structure                            */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 LABEL_H
+#define LABEL_H
+
+
+
+#include <stdio.h>
+
+/* common */
+#include "coll.h"
+
+
+
+/*****************************************************************************/
+/*                            struct CodeLabel                              */
+/*****************************************************************************/
+
+
+
+/* Label structure */
+typedef struct CodeLabel CodeLabel;
+struct CodeLabel {
+    CodeLabel*         Next;           /* Next in hash list */
+    char*              Name;           /* Label name */
+    unsigned           Hash;           /* Hash over the name */
+    struct CodeEntry*  Owner;          /* Owner entry */
+    Collection         JumpFrom;       /* Entries that jump here */
+};
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+CodeLabel* NewCodeLabel (const char* Name, unsigned Hash);
+/* Create a new code label, initialize and return it */
+
+void FreeCodeLabel (CodeLabel* L);
+/* Free the given code label */
+
+void OutputCodeLabel (FILE* F, const CodeLabel* L);
+/* Output the code label to a file */
+
+
+
+/* End of label.h */
+#endif
+
+
+
diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c
new file mode 100644 (file)
index 0000000..98f4cdd
--- /dev/null
@@ -0,0 +1,490 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                codeseg.c                                 */
+/*                                                                           */
+/*                         Code segment structure                           */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <string.h>
+#include <ctype.h>
+
+/* common */
+#include "chartype.h"
+#include "check.h"
+#include "hashstr.h"
+#include "strutil.h"
+#include "xmalloc.h"
+#include "xsprintf.h"
+
+/* b6502 */
+#include "codeent.h"
+#include "error.h"
+#include "codeseg.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+static const char* SkipSpace (const char* S)
+/* Skip white space and return an updated pointer */
+{
+    while (IsSpace (*S)) {
+       ++S;
+    }
+    return S;
+}
+
+
+
+static const char* ReadToken (const char* L, const char* Term,
+                             char* Buf, unsigned BufSize)
+/* Read the next token into Buf, return the updated line pointer. The
+ * token is terminated by one of the characters given in term.
+ */
+{
+    /* Read/copy the token */
+    unsigned I = 0;
+    unsigned ParenCount = 0;
+    while (*L && (ParenCount > 0 || strchr (Term, *L) == 0)) {
+       if (I < BufSize-1) {
+           Buf[I++] = *L;
+       }
+       if (*L == ')') {
+           --ParenCount;
+       } else if (*L == '(') {
+           ++ParenCount;
+       }
+       ++L;
+    }
+
+    /* Terminate the buffer contents */
+    Buf[I] = '\0';
+
+    /* Return the updated line pointer */
+    return L;
+}
+
+
+
+static CodeEntry* ParseInsn (const char* L)
+/* Parse an instruction nnd generate a code entry from it. If the line contains
+ * errors, output an error message and return NULL.
+ * For simplicity, we don't accept the broad range of input a "real" assembler
+ * does. The instruction and the argument are expected to be separated by
+ * white space, for example.
+ */
+{
+    char               Mnemo[16];
+    const OPCDesc*     OPC;
+    am_t               AM = 0;         /* Initialize to keep gcc silent */
+    char               Expr[64];
+    char               Reg;
+    CodeEntry*         E;
+
+    /* Mnemonic */
+    L = ReadToken (L, " \t", Mnemo, sizeof (Mnemo));
+
+    /* Try to find the opcode description for the mnemonic */
+    OPC = FindOpcode (Mnemo);
+
+    /* If we didn't find the opcode, print an error and bail out */
+    if (OPC == 0) {
+       Error ("ASM code error: %s is not a valid mnemonic", Mnemo);
+       return 0;
+    }
+
+    /* Skip separator white space */
+    L = SkipSpace (L);
+
+    /* Get the addressing mode */
+    Expr[0] = '\0';
+    switch (*L) {
+
+       case '#':
+           /* Immidiate */
+           StrCopy (Expr, sizeof (Expr), L+1);
+           AM = AM_IMM;
+           break;
+
+       case '(':
+           /* Indirect */
+           L = ReadToken (L+1, ",)", Expr, sizeof (Expr));
+
+           /* Check for errors */
+           if (*L == '\0') {
+               Error ("ASM code error: syntax error");
+               return 0;
+           }
+
+           /* Check the different indirect modes */
+                   if (*L == ',') {
+               /* Expect zp x indirect */
+               L = SkipSpace (L+1);
+               if (toupper (*L) != 'X') {
+                   Error ("ASM code error: `X' expected");
+                   return 0;
+               }
+               L = SkipSpace (L+1);
+               if (*L != ')') {
+                   Error ("ASM code error: `)' expected");
+                   return 0;
+               }
+               L = SkipSpace (L+1);
+               if (*L != '\0') {
+                   Error ("ASM code error: syntax error");
+                   return 0;
+               }
+               AM = AM_ZPX_IND;
+           } else if (*L == ')') {
+               /* zp indirect or zp indirect, y */
+               L = SkipSpace (L+1);
+               if (*L == ',') {
+                   L = SkipSpace (L+1);
+                   if (toupper (*L) != 'Y') {
+                       Error ("ASM code error: `Y' expected");
+                       return 0;
+                   }
+                   L = SkipSpace (L+1);
+                   if (*L != '\0') {
+                       Error ("ASM code error: syntax error");
+                       return 0;
+                   }
+                   AM = AM_ZP_INDY;
+               } else if (*L == '\0') {
+                   AM = AM_ZP_IND;
+               } else {
+                   Error ("ASM code error: syntax error");
+                   return 0;
+               }
+           }
+           break;
+
+       case 'a':
+               case 'A':
+           /* Accumulator? */
+           if (L[1] == '\0') {
+               AM = AM_IMP;
+               break;
+           }
+           /* FALLTHROUGH */
+
+       default:
+           /* Absolute, maybe indexed */
+           L = ReadToken (L, ",", Expr, sizeof (Expr));
+           if (*L == '\0') {
+               /* Assume absolute */
+               AM = AM_ABS;
+           } else if (*L == ',') {
+               /* Indexed */
+               L = SkipSpace (L+1);
+               if (*L == '\0') {
+                   Error ("ASM code error: syntax error");
+                   return 0;
+               } else {
+                   Reg = toupper (*L);
+                   L = SkipSpace (L+1);
+                   if (Reg == 'X') {
+                       AM = AM_ABSX;
+                   } else if (Reg == 'Y') {
+                       AM = AM_ABSY;
+                   } else {
+                       Error ("ASM code error: syntax error");
+                       return 0;
+                   }
+                   if (*L != '\0') {
+                       Error ("ASM code error: syntax error");
+                       return 0;
+                   }
+               }
+           }
+           break;
+
+    }
+
+    /* We do now have the addressing mode in AM. Allocate a new CodeEntry
+     * structure and initialize it.
+     */
+    E = NewCodeEntry (OPC, AM);
+    if (Expr[0] != '\0') {
+       /* We have an additional expression */
+       E->Arg.Expr = xstrdup (Expr);
+    }
+
+    /* Return the new code entry */
+    return E;
+}
+
+
+
+CodeSeg* NewCodeSeg (const char* Name)
+/* Create a new code segment, initialize and return it */
+{
+    unsigned I;
+
+    /* Allocate memory */
+    CodeSeg* S = xmalloc (sizeof (CodeSeg));
+
+    /* Initialize the fields */
+    S->Name = xstrdup (Name);
+    InitCollection (&S->Entries);
+    InitCollection (&S->Labels);
+    for (I = 0; I < sizeof(S->LabelHash) / sizeof(S->LabelHash[0]); ++I) {
+       S->LabelHash[I] = 0;
+    }
+
+    /* Return the new struct */
+    return S;
+}
+
+
+
+void FreeCodeSeg (CodeSeg* S)
+/* Free a code segment including all code entries */
+{
+    unsigned I, Count;
+
+    /* Free the name */
+    xfree (S->Name);
+
+    /* Free the entries */
+    Count = CollCount (&S->Entries);
+    for (I = 0; I < Count; ++I) {
+       FreeCodeEntry (CollAt (&S->Entries, I));
+    }
+
+    /* Free the collections */
+    DoneCollection (&S->Entries);
+    DoneCollection (&S->Labels);
+
+    /* Free all labels */
+    for (I = 0; I < sizeof(S->LabelHash) / sizeof(S->LabelHash[0]); ++I) {
+       CodeLabel* L = S->LabelHash[I];
+       while (L) {
+           CodeLabel* Tmp = L;
+           L = L->Next;
+           FreeCodeLabel (Tmp);
+       }
+    }
+
+    /* Free the struct */
+    xfree (S);
+}
+
+
+
+void AddCodeSegLine (CodeSeg* S, const char* Format, ...)
+/* Add a line to the given code segment */
+{
+    const char* L;
+    CodeEntry*  E;
+
+    /* Format the line */
+    va_list ap;
+    char Buf [256];
+    va_start (ap, Format);
+    xvsprintf (Buf, sizeof (Buf), Format, ap);
+    va_end (ap);
+
+    /* Skip whitespace */
+    L = SkipSpace (Buf);
+
+    /* Check which type of instruction we have */
+    E = 0;     /* Assume no insn created */
+    switch (*L) {
+
+       case '\0':
+           /* Empty line, just ignore it */
+           break;
+
+       case ';':
+           /* Comment or hint, ignore it for now */
+           break;
+
+       case '.':
+           /* Control instruction */
+           Error ("ASM code error: Pseudo instructions not supported");
+           break;
+
+       default:
+           E = ParseInsn (L);
+           break;
+    }
+
+    /* If we have a code entry, transfer the labels and insert it */
+    if (E) {
+
+       /* Transfer the labels if we have any */
+       unsigned LabelCount = CollCount (&S->Labels);
+       unsigned I;
+       for (I = 0; I < LabelCount; ++I) {
+           CollAppend (&E->Labels, CollAt (&S->Labels, I));
+       }
+       CollDeleteAll (&S->Labels);
+
+       /* Add the entry to the list of code entries in this segment */
+       CollAppend (&S->Entries, E);
+
+    }
+}
+
+
+
+void AddCodeSegLabel (CodeSeg* S, const char* Name)
+/* Add a label for the next instruction to follow */
+{
+    /* Calculate the hash from the name */
+    unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE;
+
+    /* Try to find the code label if it does already exist */
+    CodeLabel* L = FindCodeLabel (S, Name, Hash);
+
+    /* Did we find it? */
+    if (L) {
+       /* We found it - be sure it does not already have an owner */
+       CHECK (L->Owner == 0);
+    } else {
+       /* Not found - create a new one */
+       L = NewCodeLabel (Name, Hash);
+
+       /* Enter the label into the hash table */
+       L->Next = S->LabelHash[L->Hash];
+       S->LabelHash[L->Hash] = L;
+    }
+
+    /* We do now have a valid label. Remember it for later */
+    CollAppend (&S->Labels, L);
+}
+
+
+
+void OutputCodeSeg (FILE* F, const CodeSeg* S)
+/* Output the code segment data to a file */
+{
+    unsigned I;
+
+    /* Get the number of entries in this segment */
+    unsigned Count = CollCount (&S->Entries);
+
+    /* Output all entries */
+    for (I = 0; I < Count; ++I) {
+       OutputCodeEntry (F, CollConstAt (&S->Entries, I));
+    }
+}
+
+
+
+CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash)
+/* Find the label with the given name. Return the label or NULL if not found */
+{
+    /* Get the first hash chain entry */
+    CodeLabel* L = S->LabelHash[Hash];
+
+    /* Search the list */
+    while (L) {
+       if (strcmp (Name, L->Name) == 0) {
+           /* Found */
+           break;
+       }
+       L = L->Next;
+    }
+    return L;
+}
+
+
+
+void MergeCodeLabels (CodeSeg* S)
+/* Merge code labels. That means: For each instruction, remove all labels but
+ * one and adjust the code entries accordingly.
+ */
+{
+    unsigned I;
+
+    /* Walk over all code entries */
+    unsigned EntryCount = CollCount (&S->Entries);
+    for (I = 0; I < EntryCount; ++I) {
+
+               CodeLabel* RefLab;
+       unsigned   J;
+
+       /* Get a pointer to the next entry */
+       CodeEntry* E = CollAt (&S->Entries, I);
+
+       /* If this entry has one or zero labels, continue with the next one */
+       unsigned LabelCount = CollCount (&E->Labels);
+       if (LabelCount <= 1) {
+           continue;
+       }
+
+       /* We have more than one label. Use the first one as reference label */
+       RefLab = CollAt (&E->Labels, 0);
+
+       /* Walk through the remaining labels and change references to these
+        * labels to a reference to the one and only label. Delete the labels
+        * that are no longer used. To increase performance, walk backwards
+        * through the list.
+        */
+       for (J = LabelCount-1; J >= 1; --J) {
+
+           unsigned K;
+
+           /* Get the next label */
+           CodeLabel* L = CollAt (&E->Labels, J);
+
+           /* Walk through all instructions referencing this label */
+           unsigned RefCount = CollCount (&L->JumpFrom);
+           for (K = 0; K < RefCount; ++K) {
+
+               /* Get the next instrcuction that references this label */
+               CodeEntry* E = CollAt (&L->JumpFrom, K);
+
+               /* Change the reference */
+               CHECK (E->JumpTo == L);
+               E->JumpTo = RefLab;
+               CollAppend (&RefLab->JumpFrom, E);
+
+           }
+
+           /* Delete the label */
+           FreeCodeLabel (L);
+
+           /* Remove it from the list */
+           CollDelete (&E->Labels, J);
+
+       }
+    }
+}
+
+
+
diff --git a/src/cc65/codeseg.h b/src/cc65/codeseg.h
new file mode 100644 (file)
index 0000000..535cd53
--- /dev/null
@@ -0,0 +1,107 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                codeseg.h                                 */
+/*                                                                           */
+/*                         Code segment structure                           */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 CODESEG_H
+#define CODESEG_H
+
+
+
+#include <stdio.h>
+
+/* common */
+#include "attrib.h"
+#include "coll.h"
+
+/* b6502 */
+#include "label.h"
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+/* Size of the label hash table */
+#define CS_LABEL_HASH_SIZE     29
+
+/* Code segment structure */
+typedef struct CodeSeg CodeSeg;
+struct CodeSeg {
+    char*      Name;                           /* Segment name */
+    Collection Entries;                        /* List of code entries */
+    Collection Labels;                         /* Labels for next insn */
+    CodeLabel*         LabelHash [CS_LABEL_HASH_SIZE]; /* Label hash table */
+};
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+CodeSeg* NewCodeSeg (const char* Name);
+/* Create a new code segment, initialize and return it */
+
+void FreeCodeSeg (CodeSeg* S);
+/* Free a code segment including all code entries */
+
+void AddCodeSegLine (CodeSeg* S, const char* Format, ...) attribute ((format(printf,2,3)));
+/* Add a line to the given code segment */
+
+void AddCodeSegLabel (CodeSeg* S, const char* Name);
+/* Add a label for the next instruction to follow */
+
+void OutputCodeSeg (FILE* F, const CodeSeg* S);
+/* Output the code segment data to a file */
+
+CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash);
+/* Find the label with the given name. Return the label or NULL if not found */
+
+void MergeCodeLabels (CodeSeg* S);
+/* Merge code labels. That means: For each instruction, remove all labels but
+ * one and adjust the code entries accordingly.
+ */
+
+
+
+/* End of codeseg.h */
+#endif
+
+
+
diff --git a/src/cc65/dataseg.c b/src/cc65/dataseg.c
new file mode 100644 (file)
index 0000000..8940c6b
--- /dev/null
@@ -0,0 +1,132 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                dataseg.c                                 */
+/*                                                                           */
+/*                         Data segment structure                           */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 "xmalloc.h"
+#include "xsprintf.h"
+
+/* cc65 */
+#include "dataseg.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+DataSeg* NewDataSeg (void)
+/* Create a new data segment, initialize and return it */
+{
+    /* Allocate memory */
+    DataSeg* S = xmalloc (sizeof (DataSeg));
+
+    /* Initialize the fields */
+    InitCollection (&S->Lines);
+
+    /* Return the new struct */
+    return S;
+}
+
+
+
+void FreeDataSeg (DataSeg* S)
+/* Free a data segment including all line entries */
+{
+    unsigned I, Count;
+
+    /* Free the lines */
+    Count = CollCount (&S->Lines);
+    for (I = 0; I < Count; ++I) {
+       xfree (CollAt (&S->Lines, I));
+    }
+
+    /* Free the collection */
+    DoneCollection (&S->Lines);
+
+    /* Free the struct */
+    xfree (S);
+}
+
+
+
+void AppendDataSeg (DataSeg* Target, const DataSeg* Source)
+/* Append the data from Source to Target */
+{
+    unsigned I;
+
+    /* Append all lines from Source to Target */
+    unsigned Count = CollCount (&Source->Lines);
+    for (I = 0; I < Count; ++I) {
+       CollAppend (&Target->Lines, xstrdup (CollConstAt (&Source->Lines, I)));
+    }
+}
+
+
+
+void AddDataSegLine (DataSeg* S, const char* Format, ...)
+/* Add a line to the given data segment */
+{
+    va_list ap;
+    char Buf [256];
+
+    /* Format the line */
+    va_start (ap, Format);
+    xvsprintf (Buf, sizeof (Buf), Format, ap);
+    va_end (ap);
+
+    /* Add a copy to the data segment */
+    CollAppend (&S->Lines, xstrdup (Buf));
+}
+
+
+
+void OutputDataSeg (FILE* F, const DataSeg* S)
+/* Output the data segment data to a file */
+{
+    unsigned I;
+
+    /* Get the number of entries in this segment */
+    unsigned Count = CollCount (&S->Lines);
+
+    /* Output all entries */
+    for (I = 0; I < Count; ++I) {
+       fprintf (F, "%s\n", (const char*) CollConstAt (&S->Lines, I));
+    }
+}
+
+
+
diff --git a/src/cc65/dataseg.h b/src/cc65/dataseg.h
new file mode 100644 (file)
index 0000000..328962f
--- /dev/null
@@ -0,0 +1,89 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                dataseg.h                                 */
+/*                                                                           */
+/*                         Data segment structure                           */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 DATASEG_H
+#define DATASEG_H
+
+
+
+#include <stdio.h>
+
+/* common */
+#include "attrib.h"
+#include "coll.h"
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+typedef struct DataSeg DataSeg;
+struct DataSeg {
+    Collection                 Lines;          /* List of code lines */
+};
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+DataSeg* NewDataSeg (void);
+/* Create a new data segment, initialize and return it */
+
+void FreeDataSeg (DataSeg* S);
+/* Free a data segment including all line entries */
+
+void AppendDataSeg (DataSeg* Target, const DataSeg* Source);
+/* Append the data from Source to Target. */
+
+void AddDataSegLine (DataSeg* S, const char* Format, ...) attribute ((format(printf,2,3)));
+/* Add a line to the given data segment */
+
+void OutputDataSeg (FILE* F, const DataSeg* S);
+/* Output the data segment data to a file */
+
+
+
+/* End of dataseg.h */
+#endif
+
+
+
index 0ddff5a931f3ec45d25c74b14cb3eb41f1ac4fa8..ea67295a3442a3fb3a40d21abbd73545cda0c400 100644 (file)
@@ -3,30 +3,37 @@
 #
 
 
-# Library dir
+
+# ------------------------------------------------------------------------------
+
+# The executable to build
+EXE    = cc65
+
+# Library directories
 COMMON = ../common
+B6502  = b6502
 
 # Default for the compiler lib search path as compiler define
 CDEFS=-DCC65_INC=\"/usr/lib/cc65/include/\"
-CFLAGS = -O2 -g -Wall -I$(COMMON) $(CDEFS)
+CFLAGS = -O2 -g -Wall -I$(COMMON) -I$(B6502) $(CDEFS)
 CC=gcc
 EBIND=emxbind
 LDFLAGS=
 
+# ------------------------------------------------------------------------------
+# Object files and libraries to link
+
 OBJS = anonname.o      \
-       asmcode.o       \
+       asmcode.o       \
        asmlabel.o      \
-       asmline.o       \
-       codeent.o       \
-       codegen.o       \
-       codeseg.o       \
-       compile.o       \
-       cpu.o           \
-       dataseg.o       \
+       asmline.o       \
+       codegen.o       \
+       compile.o       \
+       cpu.o           \
        datatype.o      \
        declare.o       \
        declattr.o      \
-       error.o         \
+       error.o         \
        expr.o          \
        exprheap.o      \
        exprnode.o      \
@@ -42,7 +49,6 @@ OBJS =        anonname.o      \
        loop.o          \
        macrotab.o      \
        main.o          \
-       opcodes.o       \
        optimize.o      \
        preproc.o       \
        pragma.o        \
@@ -55,30 +61,32 @@ OBJS =      anonname.o      \
        typecmp.o       \
        util.o
 
-LIBS = $(COMMON)/common.a
+LIBS =         $(COMMON)/common.a      \
+       $(B6502)/b6502.a
 
-EXECS = cc65
 
+# ------------------------------------------------------------------------------
+# Makefile targets
 
+# Main target - must be first
 .PHONY: all
 ifeq (.depend,$(wildcard .depend))
-all : $(EXECS)
+all:   $(EXE)
 include .depend
 else
 all:   depend
        @$(MAKE) -f make/gcc.mak all
 endif
 
-
-cc65:  $(OBJS)
-       $(CC) $(LDFLAGS) -o cc65 $(CFLAGS) $(OBJS) $(LIBS)
-       @if [ $(OS2_SHELL) ] ;  then $(EBIND) cc65 ; fi
+$(EXE):        $(OBJS) $(LIBS)
+       $(CC) $(LDFLAGS) -o $(EXE) $(CFLAGS) $(OBJS) $(LIBS)
+       @if [ $(OS2_SHELL) ] ;  then $(EBIND) $(EXE) ; fi
 
 clean:
        rm -f *~ core *.map
 
 zap:   clean
-       rm -f *.o $(EXECS) .depend
+       rm -f *.o $(EXE) .depend
 
 # ------------------------------------------------------------------------------
 # Make the dependencies
@@ -86,6 +94,6 @@ zap:  clean
 .PHONY: depend dep
 depend dep:    $(OBJS:.o=.c)
        @echo "Creating dependency information"
-       $(CC) -I$(COMMON) -MM $^ > .depend
+       $(CC) -I$(COMMON) -I$(B6502) -MM $^ > .depend
 
 
diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c
new file mode 100644 (file)
index 0000000..84ab693
--- /dev/null
@@ -0,0 +1,204 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                opcodes.c                                 */
+/*                                                                           */
+/*                 Opcode and addressing mode definitions                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include "stdlib.h"
+#include <string.h>
+#include <ctype.h>
+
+/* common */
+#include "check.h"
+
+/* cc65 */
+#include "codeinfo.h"
+#include "opcodes.h"
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+/* Mapper table, mnemonic --> opcode */
+static const OPCDesc OPCTable[OPC_COUNT] = {
+    { "adc", OPC_ADC, CI_USE_A | CI_CHG_A      },
+    { "and", OPC_AND, CI_USE_A | CI_CHG_A      },
+    { "asl", OPC_ASL, CI_USE_A | CI_CHG_A      },
+    { "bcc", OPC_BCC, CI_CHG_NONE              },
+    { "bcs", OPC_BCS, CI_CHG_NONE              },
+    { "beq", OPC_BEQ, CI_CHG_NONE              },
+    { "bit", OPC_BIT, CI_USE_A                         },
+    { "bmi", OPC_BMI, CI_CHG_NONE              },
+    { "bne", OPC_BNE, CI_CHG_NONE              },
+    { "bpl", OPC_BPL, CI_CHG_NONE              },
+    { "bra", OPC_BRA, CI_CHG_NONE              },
+    { "brk", OPC_BRK, CI_CHG_NONE              },
+    { "bvc", OPC_BVC, CI_CHG_NONE              },
+    { "bvs", OPC_BVS, CI_CHG_NONE              },
+    { "clc", OPC_CLC, CI_CHG_NONE              },
+    { "cld", OPC_CLD, CI_CHG_NONE              },
+    { "cli", OPC_CLI, CI_CHG_NONE              },
+    { "clv", OPC_CLV, CI_CHG_NONE              },
+    { "cmp", OPC_CMP, CI_USE_A                 },
+    { "cpx", OPC_CPX, CI_USE_X                 },
+    { "cpy", OPC_CPY, CI_USE_Y                 },
+    { "dea", OPC_DEA, CI_USE_A | CI_CHG_A      },
+    { "dec", OPC_DEC, CI_NONE                  },
+    { "dex", OPC_DEX, CI_USE_X | CI_CHG_X      },
+    { "dey", OPC_DEY, CI_USE_Y | CI_CHG_Y      },
+    { "eor", OPC_EOR, CI_USE_A | CI_CHG_A      },
+    { "ina", OPC_INA, CI_USE_A | CI_CHG_A      },
+    { "inc", OPC_INC, CI_NONE                  },
+    { "inx", OPC_INX, CI_USE_X | CI_CHG_X      },
+    { "iny", OPC_INY, CI_USE_Y | CI_CHG_Y      },
+    { "jmp", OPC_JMP, CI_NONE                  },
+    { "jsr", OPC_JSR, CI_NONE                  },
+    { "lda", OPC_LDA, CI_CHG_A                 },
+    { "ldx", OPC_LDX, CI_CHG_X                 },
+    { "ldy", OPC_LDY, CI_CHG_Y                 },
+    { "lsr", OPC_LSR, CI_USE_A | CI_CHG_A      },
+    { "nop", OPC_NOP, CI_NONE                  },
+    { "ora", OPC_ORA, CI_USE_A | CI_CHG_A      },
+    { "pha", OPC_PHA, CI_USE_A                 },
+    { "php", OPC_PHP, CI_NONE                  },
+    { "phx", OPC_PHX, CI_USE_X                 },
+    { "phy", OPC_PHY, CI_USE_Y                 },
+    { "pla", OPC_PLA, CI_CHG_A                 },
+    { "plp", OPC_PLP, CI_NONE                  },
+    { "plx", OPC_PLX, CI_CHG_X                 },
+    { "ply", OPC_PLY, CI_CHG_Y                 },
+    { "rol", OPC_ROL, CI_USE_A | CI_CHG_A      },
+    { "ror", OPC_ROR, CI_USE_A | CI_CHG_A      },
+    { "rti", OPC_RTI, CI_NONE                  },
+    { "rts", OPC_RTS, CI_NONE                  },
+    { "sbc", OPC_SBC, CI_USE_A | CI_CHG_A      },
+    { "sec", OPC_SEC, CI_NONE                  },
+    { "sed", OPC_SED, CI_NONE                  },
+    { "sei", OPC_SEI, CI_NONE                  },
+    { "sta", OPC_STA, CI_USE_A                 },
+    { "stx", OPC_STX, CI_USE_X                 },
+    { "sty", OPC_STY, CI_USE_Y                 },
+    { "tax", OPC_TAX, CI_USE_A | CI_CHG_X      },
+    { "tay", OPC_TAY, CI_USE_A | CI_CHG_Y      },
+    { "trb", OPC_TRB, CI_USE_A                 },
+    { "tsb", OPC_TSB, CI_USE_A                 },
+    { "tsx", OPC_TSX, CI_CHG_X                 },
+    { "txa", OPC_TXA, CI_USE_X | CI_CHG_A      },
+    { "txs", OPC_TXS, CI_USE_X                 },
+    { "tya", OPC_TYA, CI_USE_Y | CI_CHG_A      }
+};
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+static int Compare (const void* Key, const void* Desc)
+/* Compare function for bsearch */
+{
+    return strcmp (Key, ((OPCDesc*)Desc)->Mnemo);
+}
+
+
+
+const OPCDesc* FindOpcode (const char* M)
+/* Find the given opcode and return the opcode number. If the opcode was not
+ * found, return OPC_INVALID.
+ */
+{
+    unsigned I;
+    unsigned Len;
+
+    /* Check the length of the given string, then copy it into local
+     * storage, converting it to upper case.
+     */
+    char Mnemo[sizeof (OPCTable[0].Mnemo)];
+    Len = strlen (M);
+    if (Len >= sizeof (OPCTable[0].Mnemo)) {
+       /* Invalid length means invalid opcode */
+       return 0;
+    }
+    for (I = 0; I < Len; ++I) {
+       Mnemo[I] = tolower (M[I]);
+    }
+    Mnemo[I] = '\0';
+
+    /* Search for the mnemonic in the table and return the result */
+    return bsearch (Mnemo, OPCTable, OPC_COUNT, sizeof (OPCTable[0]), Compare);
+}
+
+
+
+unsigned GetInsnSize (opc_t OPC, am_t AM)
+/* Return the size of the given instruction */
+{
+    /* On the 6502 (and 65C02), the instruction size is determined only by the
+     * addressing mode.
+     */
+    switch (AM) {
+       case AM_IMP:      return 1;
+       case AM_IMM:      return 2;
+       case AM_ZP:       return 2;
+       case AM_ZPX:      return 2;
+       case AM_ABS:      return 3;
+       case AM_ABSX:     return 3;
+       case AM_ABSY:     return 3;
+       case AM_ZPX_IND:  return 2;
+       case AM_ZP_INDY:  return 2;
+       case AM_ZP_IND:   return 2;
+       case AM_BRA:      return 2;
+       default:          FAIL ("Invalid addressing mode");
+    }
+}
+
+
+
+const OPCDesc* GetOPCDesc (opc_t OPC)
+/* Get an opcode description */
+{
+    /* Check the range */
+    PRECONDITION (OPC >= (opc_t)0 && OPC < OPC_COUNT);
+
+    /* Return the description */
+    return &OPCTable [OPC];
+}
+
+
+
+                         
diff --git a/src/cc65/opcodes.h b/src/cc65/opcodes.h
new file mode 100644 (file)
index 0000000..7bcda63
--- /dev/null
@@ -0,0 +1,164 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                opcodes.h                                 */
+/*                                                                           */
+/*                 Opcode and addressing mode definitions                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 OPCODES_H
+#define OPCODES_H
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
+/*****************************************************************************/
+
+
+
+/* Definitions for the possible opcodes */
+typedef enum {
+    OPC_ADC,
+    OPC_AND,
+    OPC_ASL,
+    OPC_BCC,
+    OPC_BCS,
+    OPC_BEQ,
+    OPC_BIT,
+    OPC_BMI,
+    OPC_BNE,
+    OPC_BPL,
+    OPC_BRA,
+    OPC_BRK,
+    OPC_BVC,
+    OPC_BVS,
+    OPC_CLC,
+    OPC_CLD,
+    OPC_CLI,
+    OPC_CLV,
+    OPC_CMP,
+    OPC_CPX,
+    OPC_CPY,
+    OPC_DEA,
+    OPC_DEC,
+    OPC_DEX,
+    OPC_DEY,
+    OPC_EOR,
+    OPC_INA,
+    OPC_INC,
+    OPC_INX,
+    OPC_INY,
+    OPC_JMP,
+    OPC_JSR,
+    OPC_LDA,
+    OPC_LDX,
+    OPC_LDY,
+    OPC_LSR,
+    OPC_NOP,
+    OPC_ORA,
+    OPC_PHA,
+    OPC_PHP,
+    OPC_PHX,
+    OPC_PHY,
+    OPC_PLA,
+    OPC_PLP,
+    OPC_PLX,
+    OPC_PLY,
+    OPC_ROL,
+    OPC_ROR,
+    OPC_RTI,
+    OPC_RTS,
+    OPC_SBC,
+    OPC_SEC,
+    OPC_SED,
+    OPC_SEI,
+    OPC_STA,
+    OPC_STX,
+    OPC_STY,
+    OPC_TAX,
+    OPC_TAY,
+    OPC_TRB,
+    OPC_TSB,
+    OPC_TSX,
+    OPC_TXA,
+    OPC_TXS,
+    OPC_TYA,
+    OPC_COUNT                  /* Number of opcodes available */
+} opc_t;
+
+/* Addressing modes (bitmapped). */
+typedef enum {
+    AM_IMP     = 0x0001,       /* implicit + accumulator */
+    AM_IMM     = 0x0002,       /* immidiate */
+    AM_ZP              = 0x0004,       /* zeropage */
+    AM_ZPX     = 0x0008,       /* zeropage,X */
+    AM_ABS     = 0x0010,       /* absolute */
+    AM_ABSX    = 0x0020,       /* absolute,X */
+    AM_ABSY            = 0x0040,       /* absolute,Y */
+    AM_ZPX_IND = 0x0080,       /* (zeropage,x) */
+    AM_ZP_INDY = 0x0100,       /* (zeropage),y */
+    AM_ZP_IND  = 0x0200,       /* (zeropage) */
+    AM_BRA     = 0x0400        /* branch */
+} am_t;
+
+/* Opcode description */
+typedef struct {
+    char       Mnemo[4];       /* Mnemonic */
+    opc_t      OPC;            /* Opcode */
+    unsigned   Usage;          /* Usage flags */
+} OPCDesc;
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+const OPCDesc* FindOpcode (const char* OPC);
+/* Find the given opcode and return the opcode description. If the opcode was
+ * not found, NULL is returned.
+ */
+
+unsigned GetInsnSize (opc_t OPC, am_t AM);
+/* Return the size of the given instruction */
+
+const OPCDesc* GetOPCDesc (opc_t OPC);
+/* Get an opcode description */
+
+
+
+/* End of opcodes.h */
+#endif
+
+
+