]> git.sur5r.net Git - cc65/commitdiff
First import
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 8 Feb 2003 16:32:55 +0000 (16:32 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 8 Feb 2003 16:32:55 +0000 (16:32 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1942 b7a2c559-68d2-44c3-8de9-860c34a00d81

12 files changed:
src/co65/.cvsignore [new file with mode: 0644]
src/co65/error.c [new file with mode: 0644]
src/co65/error.h [new file with mode: 0644]
src/co65/fileio.c [new file with mode: 0644]
src/co65/fileio.h [new file with mode: 0644]
src/co65/global.c [new file with mode: 0644]
src/co65/global.h [new file with mode: 0644]
src/co65/main.c [new file with mode: 0644]
src/co65/make/gcc.mak [new file with mode: 0644]
src/co65/make/watcom.mak [new file with mode: 0644]
src/co65/o65.c [new file with mode: 0644]
src/co65/o65.h [new file with mode: 0644]

diff --git a/src/co65/.cvsignore b/src/co65/.cvsignore
new file mode 100644 (file)
index 0000000..bc95643
--- /dev/null
@@ -0,0 +1,2 @@
+.depend
+co65
diff --git a/src/co65/error.c b/src/co65/error.c
new file mode 100644 (file)
index 0000000..da0f8ad
--- /dev/null
@@ -0,0 +1,94 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                error.c                                   */
+/*                                                                           */
+/*             Error handling for the co65 object file converter             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+/* common */
+#include "cmdline.h"
+
+/* co65 */
+#include "error.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void Warning (const char* Format, ...)
+/* Print a warning message */
+{
+    va_list ap;
+    va_start (ap, Format);
+    fprintf (stderr, "%s: Warning: ", ProgName);
+    vfprintf (stderr, Format, ap);
+    putc ('\n', stderr);
+    va_end (ap);
+}
+
+
+
+void Error (const char* Format, ...)
+/* Print an error message and die */
+{
+    va_list ap;
+    va_start (ap, Format);
+    fprintf (stderr, "%s: Error: ", ProgName);
+    vfprintf (stderr, Format, ap);
+    putc ('\n', stderr);
+    va_end (ap);
+    exit (EXIT_FAILURE);
+}
+
+
+
+void Internal (const char* Format, ...)
+/* Print an internal error message and die */
+{
+    va_list ap;     
+    va_start (ap, Format);
+    fprintf (stderr, "%s: Internal error: ", ProgName);
+    vfprintf (stderr, Format, ap);
+    putc ('\n', stderr);
+    va_end (ap);
+    exit (EXIT_FAILURE);
+}
+
+
+
diff --git a/src/co65/error.h b/src/co65/error.h
new file mode 100644 (file)
index 0000000..9eab1e7
--- /dev/null
@@ -0,0 +1,68 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                error.h                                   */
+/*                                                                           */
+/*             Error handling for the co65 object file converter             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef ERROR_H
+#define ERROR_H
+
+
+
+/* common */
+#include "attrib.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void Warning (const char* Format, ...) attribute((format(printf,1,2)));
+/* Print a warning message */
+
+void Error (const char* Format, ...) attribute((format(printf,1,2)));
+/* Print an error message and die */
+
+void Internal (const char* Format, ...) attribute((format(printf,1,2)));
+/* Print an internal error message and die */
+
+
+
+/* End of error.h */
+
+#endif
+
+
+
diff --git a/src/co65/fileio.c b/src/co65/fileio.c
new file mode 100644 (file)
index 0000000..1b0d58c
--- /dev/null
@@ -0,0 +1,108 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                fileio.c                                  */
+/*                                                                           */
+/*              Binary file I/O for the co65 object file converter           */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <string.h>
+
+/* common */
+#include "xmalloc.h"
+
+/* ld65 */
+#include "error.h"
+#include "fileio.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+unsigned Read8 (FILE* F)
+/* Read an 8 bit value from the file */
+{
+    int C = getc (F);
+    if (C == EOF) {
+       Error ("Read error (file corrupt?)");
+    }
+    return C;
+}
+
+
+
+unsigned Read16 (FILE* F)
+/* Read a 16 bit value from the file */
+{
+    unsigned Lo = Read8 (F);
+    unsigned Hi = Read8 (F);
+    return (Hi << 8) | Lo;
+}
+
+
+
+unsigned long Read24 (FILE* F)
+/* Read a 24 bit value from the file */
+{
+    unsigned long Lo = Read16 (F);
+    unsigned long Hi = Read8 (F);
+    return (Hi << 16) | Lo;
+}
+
+
+
+unsigned long Read32 (FILE* F)
+/* Read a 32 bit value from the file */
+{
+    unsigned long Lo = Read16 (F);
+    unsigned long Hi = Read16 (F);
+    return (Hi << 16) | Lo;
+}
+
+
+
+void* ReadData (FILE* F, void* Data, unsigned Size)
+/* Read data from the file */
+{
+    /* Explicitly allow reading zero bytes */
+    if (Size > 0) {
+       if (fread (Data, 1, Size, F) != Size) {
+           Error ("Read error (file corrupt?)");
+       }
+    }
+    return Data;
+}
+
+
+
diff --git a/src/co65/fileio.h b/src/co65/fileio.h
new file mode 100644 (file)
index 0000000..aedfddb
--- /dev/null
@@ -0,0 +1,76 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                fileio.h                                  */
+/*                                                                           */
+/*              Binary file I/O for the co65 object file converter           */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef FILEIO_H
+#define FILEIO_H
+
+
+
+#include <stdio.h>
+
+/* common */
+#include "filepos.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+unsigned Read8 (FILE* F);
+/* Read an 8 bit value from the file */
+
+unsigned Read16 (FILE* F);
+/* Read a 16 bit value from the file */
+
+unsigned long Read24 (FILE* F);
+/* Read a 24 bit value from the file */
+
+unsigned long Read32 (FILE* F);
+/* Read a 32 bit value from the file */
+
+void* ReadData (FILE* F, void* Data, unsigned Size);
+/* Read data from the file */
+
+
+
+/* End of fileio.h */
+
+#endif
+
+
+
diff --git a/src/co65/global.c b/src/co65/global.c
new file mode 100644 (file)
index 0000000..ed65c9c
--- /dev/null
@@ -0,0 +1,67 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                global.c                                  */
+/*                                                                           */
+/*            Global variables for the co65 object file converter            */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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 "segnames.h"
+
+/* co65 */
+#include "global.h"
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* File names */
+const char* InFilename      = 0;                /* Name of input file */
+const char* OutFilename     = 0;                /* Name of output file */
+
+/* Default extensions */
+const char AsmExt[]         = ".s";             /* Default assembler extension */
+
+/* Segment names */
+const char* CodeSeg         = SEGNAME_CODE;     /* Name of the code segment */
+const char* DataSeg         = SEGNAME_DATA;     /* Name of the data segment */
+const char* BssSeg          = SEGNAME_BSS;      /* Name of the bss segment */
+const char* ZeropageSeg     = SEGNAME_ZEROPAGE; /* Name of the zeropage segment */
+
+/* Flags */
+unsigned char DebugInfo     = 0;                /* Enable debug info */
+
+
+
diff --git a/src/co65/global.h b/src/co65/global.h
new file mode 100644 (file)
index 0000000..634537b
--- /dev/null
@@ -0,0 +1,70 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                global.h                                  */
+/*                                                                           */
+/*            Global variables for the co65 object file converter            */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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 GLOBAL_H
+#define GLOBAL_H
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* File names */
+extern const char*             InFilename;         /* Name of input file */
+extern const char*             OutFilename;        /* Name of output file */
+
+/* Default extensions */
+extern const char              AsmExt[];           /* Default assembler extension */
+
+/* Segment names */
+extern const char*      CodeSeg;            /* Name of the code segment */
+extern const char*      DataSeg;            /* Name of the data segment */
+extern const char*      BssSeg;             /* Name of the bss segment */
+extern const char*      ZeropageSeg;        /* Name of the zeropage segment */
+
+/* Flags */
+extern unsigned char    DebugInfo;          /* Enable debug info */
+
+
+
+/* End of global.h */
+
+#endif
+
+
+
diff --git a/src/co65/main.c b/src/co65/main.c
new file mode 100644 (file)
index 0000000..a206f56
--- /dev/null
@@ -0,0 +1,490 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 main.c                                   */
+/*                                                                           */
+/*              Main program for the co65 object file converter              */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+/* common */
+#include "cmdline.h"
+#include "fname.h"
+#include "print.h"
+#include "segnames.h"
+#include "version.h"
+#include "xmalloc.h"
+#include "xsprintf.h"
+
+/* co65 */
+#include "error.h"
+#include "global.h"
+#include "o65.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+static void Usage (void)
+/* Print usage information and exit */
+{
+    fprintf (stderr,
+            "Usage: %s [options] file\n"
+            "Short options:\n"
+                    "  -V\t\t\tPrint the version number\n"
+                    "  -g\t\t\tAdd debug info to object file\n"
+                    "  -h\t\t\tHelp (this text)\n"
+                    "  -o name\t\tName the output file\n"
+                    "  -v\t\t\tIncrease verbosity\n"
+            "\n"
+            "Long options:\n"
+            "  --bss-name seg\tSet the name of the BSS segment\n"
+                    "  --code-name seg\tSet the name of the CODE segment\n"
+                    "  --data-name seg\tSet the name of the DATA segment\n"
+                    "  --debug-info\t\tAdd debug info to object file\n"
+            "  --help\t\tHelp (this text)\n"
+                    "  --verbose\t\tIncrease verbosity\n"
+                    "  --version\t\tPrint the version number\n"
+                    "  --zeropage-name seg\tSet the name of the ZEROPAGE segment\n",
+            ProgName);
+}
+
+
+
+static void CheckSegName (const char* Seg)
+/* Abort if the given name is not a valid segment name */
+{
+    /* Print an error and abort if the name is not ok */
+    if (!ValidSegName (Seg)) {
+       Error ("Segment name `%s' is invalid", Seg);
+    }
+}
+
+
+
+static void OptBssName (const char* Opt attribute ((unused)), const char* Arg)
+/* Handle the --bss-name option */
+{
+    /* Check for a valid name */
+    CheckSegName (Arg);
+
+    /* Set the name */
+    BssSeg = xstrdup (Arg);
+}
+
+
+
+static void OptCodeName (const char* Opt attribute ((unused)), const char* Arg)
+/* Handle the --code-name option */
+{
+    /* Check for a valid name */
+    CheckSegName (Arg);
+
+    /* Set the name */
+    CodeSeg = xstrdup (Arg);
+}
+
+
+
+static void OptDataName (const char* Opt attribute ((unused)), const char* Arg)
+/* Handle the --data-name option */
+{
+    /* Check for a valid name */
+    CheckSegName (Arg);
+
+    /* Set the name */
+    DataSeg = xstrdup (Arg);
+}
+
+
+
+static void OptDebugInfo (const char* Opt attribute ((unused)),
+                         const char* Arg attribute ((unused)))
+/* Add debug info to the object file */
+{
+    DebugInfo = 1;
+}
+
+
+
+static void OptHelp (const char* Opt attribute ((unused)),
+                    const char* Arg attribute ((unused)))
+/* Print usage information and exit */
+{
+    Usage ();
+    exit (EXIT_SUCCESS);
+}
+
+
+
+static void OptVerbose (const char* Opt attribute ((unused)),
+                       const char* Arg attribute ((unused)))
+/* Increase verbosity */
+{
+    ++Verbosity;
+}
+
+
+
+static void OptVersion (const char* Opt attribute ((unused)),
+                       const char* Arg attribute ((unused)))
+/* Print the assembler version */
+{
+    fprintf (stderr,
+                    "co65 V%u.%u.%u - (C) Copyright 1998-2003 Ullrich von Bassewitz\n",
+                    VER_MAJOR, VER_MINOR, VER_PATCH);
+}
+
+
+
+static void OptZeropageName (const char* Opt attribute ((unused)), const char* Arg)
+/* Handle the --zeropage-name option */
+{
+    /* Check for a valid name */
+    CheckSegName (Arg);
+
+    /* Set the name */
+    ZeropageSeg = xstrdup (Arg);
+}
+
+
+
+static const char* SegReloc (const O65Data* D, const O65Reloc* R, unsigned long Val)
+{
+    static char Buf[256];
+    const O65Import* Import;
+
+    switch (R->SegID) {
+
+        case O65_SEGID_UNDEF:
+            if (R->SymIdx >= CollCount (&D->Imports)) {
+                Error ("Import index out of range (input file corrupt)");
+            }
+            Import = CollConstAt (&D->Imports, R->SymIdx);
+            xsprintf (Buf, sizeof (Buf), "%s%+ld", Import->Name, (long) Val);
+            break;
+
+        case O65_SEGID_TEXT:
+            xsprintf (Buf, sizeof (Buf), "%s%+ld", CodeSeg, (long) (Val - D->Header.tbase));
+            break;
+
+        case O65_SEGID_DATA:
+            xsprintf (Buf, sizeof (Buf), "%s%+ld", DataSeg, (long) (Val - D->Header.dbase));
+            break;
+
+        case O65_SEGID_BSS:
+            xsprintf (Buf, sizeof (Buf), "%s%+ld", BssSeg, (long) (Val - D->Header.bbase));
+            break;
+
+        case O65_SEGID_ZP:
+            xsprintf (Buf, sizeof (Buf), "%s%+ld", ZeropageSeg, (long) Val - D->Header.zbase);
+            break;
+
+        case O65_SEGID_ABS:
+            Error ("Relocation entry contains O65_SEGID_ABS");
+            break;
+
+        default:
+            Internal ("Cannot handle this segment reference in reloc entry");
+    }
+
+    return Buf;
+}
+
+
+
+static void ConvertSeg (FILE* F, const O65Data* D, const Collection* Relocs,
+                        const unsigned char* Data, unsigned long Size)
+/* Convert one segment */
+{
+    const O65Reloc* R;
+    unsigned        RIdx;
+    unsigned long   Byte;
+
+    /* Get the pointer to the first relocation entry if there are any */
+    R = (CollCount (Relocs) > 0)? CollConstAt (Relocs, 0) : 0;
+
+    /* Initialize for the loop */
+    RIdx = 0;
+    Byte = 0;
+
+    /* Walk over the segment data */
+    while (Byte < Size) {
+
+        if (R && R->Offs == Byte) {
+            /* We've reached an entry that must be relocated */
+            unsigned long Val;
+            switch (R->Type) {
+
+                case O65_RTYPE_WORD:
+                    if (Byte >= Size - 1) {
+                        Error ("Found WORD relocation, but not enough bytes left");
+                    } else {
+                        Val = (Data[Byte+1] << 8) + Data[Byte];
+                        Byte += 2;
+                        fprintf (F, "\t.word\t%s\n", SegReloc (D, R, Val));
+                    }
+                    break;
+
+                case O65_RTYPE_HIGH:
+                    Val = (Data[Byte++] << 8) + R->Val;
+                    fprintf (F, "\t.byte\t>(%s)\n", SegReloc (D, R, Val));
+                    break;
+
+                case O65_RTYPE_LOW:
+                    Val = Data[Byte++];
+                    fprintf (F, "\t.byte\t<(%s)\n", SegReloc (D, R, Val));
+                    break;
+
+                case O65_RTYPE_SEGADDR:
+                    if (Byte >= Size - 2) {
+                        Error ("Found SEGADDR relocation, but not enough bytes left");
+                    } else {
+                        Val = (((unsigned long) Data[Byte+2]) << 16) +
+                              (((unsigned long) Data[Byte+1]) <<  8) +
+                              (((unsigned long) Data[Byte+0]) <<  0) +
+                              R->Val;
+                        Byte += 3;
+                        fprintf (F, "\t.faraddr\t%s\n", SegReloc (D, R, Val));
+                    }
+                    break;
+                case O65_RTYPE_SEG:
+                default:
+                    Internal ("Invalid relocation type at %lu", Byte);
+            }
+
+            /* Get the next relocation entry */
+            if (++RIdx < CollCount (Relocs)) {
+                R = CollConstAt (Relocs, RIdx);
+            } else {
+                R = 0;
+            }
+
+        } else {
+            /* Just a constant value */
+            fprintf (F, "\t.byte\t$%02X\n", Data[Byte++]);
+        }
+    }
+
+    fprintf (F, "\n");
+}
+
+
+
+static void Convert (void)
+/* Do file conversion */
+{
+    FILE* F;
+    unsigned  I;
+
+    /* Read the o65 file into memory */
+    O65Data* D = ReadO65File (InFilename);
+
+    /* For now, we do only accept o65 files generated by the ld65 linker which
+     * have a specific format.
+     */
+    if (D->Header.mode != O65_MODE_CC65) {
+        Error ("Cannot convert o65 files of this type");
+    }
+
+    printf ("Textsize:   %lu\n", D->Header.tlen);
+    printf ("Datasize:   %lu\n", D->Header.dlen);
+    printf ("Imports:    %u\n", CollCount (&D->Imports));
+    printf ("Exports:    %u\n", CollCount (&D->Exports));
+    printf ("Textrelocs: %u\n", CollCount (&D->TextReloc));
+    printf ("Datarelocs: %u\n", CollCount (&D->DataReloc));
+
+    /* Open the output file */
+    F = fopen (OutFilename, "wb");
+    if (F == 0) {
+        Error ("Cannot open `%s': %s", OutFilename, strerror (errno));
+    }
+
+    /* Create a header */
+    if ((D->Header.mode & O65_CPU_MASK) == O65_CPU_65816) {
+       fprintf (F, "\t.p816\n");
+    }
+    fprintf (F, ";\n; File generated by co65 v %u.%u.%u\n;\n",
+             VER_MAJOR, VER_MINOR, VER_PATCH);
+    fprintf (F, "\t.fopt\t\tcompiler,\"co65 v %u.%u.%u\"\n",
+             VER_MAJOR, VER_MINOR, VER_PATCH);
+    fprintf (F, "\t.case\t\ton\n");
+    fprintf (F, "\t.debuginfo\t%s\n", (DebugInfo != 0)? "on" : "off");
+    fprintf (F, "\n");
+
+    /* Imported identifiers */
+    if (CollCount (&D->Imports) > 0) {
+        for (I = 0; I < CollCount (&D->Imports); ++I) {
+
+            /* Get the next import */
+            O65Import* Import = CollAtUnchecked (&D->Imports, I);
+
+            /* Import it by name */
+            fprintf (F, "\t.import\t%s\n", Import->Name);
+        }
+        fprintf (F, "\n");
+    }
+
+    /* Exported identifiers */
+    if (CollCount (&D->Exports) > 0) {
+        for (I = 0; I < CollCount (&D->Exports); ++I) {
+
+            /* Get the next import */
+            O65Export* Export = CollAtUnchecked (&D->Exports, I);
+
+            /* Import it by name */
+            fprintf (F, "\t.export\t%s\n", Export->Name);
+        }
+        fprintf (F, "\n");
+    }
+
+    /* Code segment */
+    fprintf (F, ".segment\t\"%s\"\n", CodeSeg);
+    fprintf (F, "%s:\n", CodeSeg);
+    ConvertSeg (F, D, &D->TextReloc, D->Text, D->Header.tlen);
+
+    /* Data segment */
+    fprintf (F, ".segment\t\"%s\"\n", DataSeg);
+    fprintf (F, "%s:\n", DataSeg);
+    ConvertSeg (F, D, &D->DataReloc, D->Data, D->Header.dlen);
+
+    /* BSS segment */
+    fprintf (F, ".segment\t\"%s\"\n", BssSeg);
+    fprintf (F, "%s:\n", BssSeg);
+    fprintf (F, "\t.res\t%lu\n", D->Header.blen);
+    fprintf (F, "\n");
+
+    fprintf (F, "\t.end\n");
+    fclose (F);
+}
+
+
+
+int main (int argc, char* argv [])
+/* Converter main program */
+{
+    /* Program long options */
+    static const LongOpt OptTab[] = {
+       { "--bss-name",         1,      OptBssName              },
+       { "--code-name",        1,      OptCodeName             },
+       { "--data-name",        1,      OptDataName             },
+       { "--debug-info",       0,      OptDebugInfo            },
+       { "--help",             0,      OptHelp                 },
+       { "--verbose",          0,      OptVerbose              },
+       { "--version",          0,      OptVersion              },
+               { "--zeropage-name",    1,      OptZeropageName         },
+    };
+
+    unsigned I;
+
+    /* Initialize the cmdline module */
+    InitCmdLine (&argc, &argv, "co65");
+
+    /* Check the parameters */
+    I = 1;
+    while (I < ArgCount) {
+
+               /* Get the argument */
+               const char* Arg = ArgVec [I];
+
+               /* Check for an option */
+               if (Arg [0] == '-') {
+                   switch (Arg [1]) {
+
+               case '-':
+                   LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
+                   break;
+
+               case 'g':
+                   OptDebugInfo (Arg, 0);
+                   break;
+
+               case 'h':
+                   OptHelp (Arg, 0);
+                   break;
+
+                       case 'o':
+                           OutFilename = GetArg (&I, 2);
+                           break;
+
+                       case 'v':
+                   OptVerbose (Arg, 0);
+                           break;
+
+                       case 'V':
+                   OptVersion (Arg, 0);
+                           break;
+
+                       default:
+                           UnknownOption (Arg);
+                   break;
+
+           }
+               } else {
+           /* Filename. Check if we already had one */
+           if (InFilename) {
+               Error ("Don't know what to do with `%s'\n", Arg);
+           } else {
+               InFilename = Arg;
+           }
+       }
+
+       /* Next argument */
+       ++I;
+    }
+
+    /* Do we have an input file? */
+    if (InFilename == 0) {
+               Error ("No input file\n");
+    }
+
+    /* Generate the name of the output file if none was specified */
+    if (OutFilename == 0) {
+        OutFilename = MakeFilename (InFilename, AsmExt);
+    }
+
+    /* Do the conversion */
+    Convert ();
+
+    /* Return an apropriate exit code */
+    return EXIT_SUCCESS;
+}
+
+
+
diff --git a/src/co65/make/gcc.mak b/src/co65/make/gcc.mak
new file mode 100644 (file)
index 0000000..7b0cb39
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# gcc Makefile for co65
+#
+
+# Library dir
+COMMON = ../common
+
+CFLAGS         = -g -O2 -Wall -W -I$(COMMON)
+CC     = gcc
+EBIND  = emxbind
+LDFLAGS        =
+
+OBJS = error.o         \
+        fileio.o        \
+        global.o        \
+        main.o          \
+        o65.o
+
+LIBS = $(COMMON)/common.a
+
+EXECS = co65
+
+.PHONY: all
+ifeq (.depend,$(wildcard .depend))
+all : $(EXECS)
+include .depend
+else
+all:   depend
+       @$(MAKE) -f make/gcc.mak all
+endif
+
+
+
+co65:   $(OBJS) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
+       @if [ $(OS2_SHELL) ] ;  then $(EBIND) $@ ; fi
+
+clean:
+       rm -f *~ core *.lst
+
+zap:   clean
+       rm -f *.o $(EXECS) .depend
+
+# ------------------------------------------------------------------------------
+# Make the dependencies
+
+.PHONY: depend dep
+depend dep:    $(OBJS:.o=.c)
+       @echo "Creating dependency information"
+       $(CC) -I$(COMMON) -MM $^ > .depend
+
+
diff --git a/src/co65/make/watcom.mak b/src/co65/make/watcom.mak
new file mode 100644 (file)
index 0000000..42f9918
--- /dev/null
@@ -0,0 +1,82 @@
+#
+# CO65 Makefile for the Watcom compiler (using GNU make)
+#
+
+# ------------------------------------------------------------------------------
+# Generic stuff
+
+AR     = WLIB
+LD     = WLINK
+LNKCFG  = ld.tmp
+
+# --------------------- OS2 ---------------------
+ifeq ($(TARGET),OS2)
+SYSTEM  = os2v2
+CC      = WCC386
+CFLAGS  = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
+endif
+
+# -------------------- DOS4G --------------------
+ifeq ($(TARGET),DOS32)
+SYSTEM  = dos4g
+CC      = WCC386
+CFLAGS  = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
+endif
+
+# --------------------- NT ----------------------
+ifeq ($(TARGET),NT)
+SYSTEM  = nt
+CC      = WCC386
+CFLAGS  = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
+endif
+
+# Add the include dir
+CFLAGS  += -i=..\common
+
+# ------------------------------------------------------------------------------
+# Implicit rules
+
+%.obj:  %.c
+       $(CC) $(CFLAGS) $^
+
+
+# ------------------------------------------------------------------------------
+# All library OBJ files
+
+OBJS =         error.obj       \
+        fileio.obj      \
+        global.obj      \
+        main.obj        \
+        o65.obj
+
+LIBS = ..\common\common.lib
+
+
+# ------------------------------------------------------------------------------
+# Main targets
+
+all:           co65
+
+co65:          co65.exe
+
+
+# ------------------------------------------------------------------------------
+# Other targets
+
+
+co65.exe:      $(OBJS) $(LIBS)
+       @echo DEBUG ALL > $(LNKCFG)
+       @echo OPTION QUIET >> $(LNKCFG)
+       @echo NAME $@ >> $(LNKCFG)
+       @for %%i in ($(OBJS)) do echo FILE %%i >> $(LNKCFG)
+       @for %%i in ($(LIBS)) do echo LIBRARY %%i >> $(LNKCFG)
+       $(LD) system $(SYSTEM) @$(LNKCFG)
+       @rm $(LNKCFG)
+
+clean:
+       @if exist *.obj del *.obj
+       @if exist co65.exe del co65.exe
+
+strip:
+       @-wstrip co65.exe
+
diff --git a/src/co65/o65.c b/src/co65/o65.c
new file mode 100644 (file)
index 0000000..aa000f3
--- /dev/null
@@ -0,0 +1,369 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                  o65.h                                   */
+/*                                                                           */
+/*               Definitions and code for the o65 file format                */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2002-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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+/* common */
+#include "xmalloc.h"
+
+/* co65 */
+#include "error.h"
+#include "fileio.h"
+#include "o65.h"
+
+
+
+/*****************************************************************************/
+/*                              struct O65Data                               */
+/*****************************************************************************/
+
+
+
+static O65Data* NewO65Data (void)
+/* Create, initialize and return a new O65Data struct */
+{
+    /* Allocate memory */
+    O65Data* D = xmalloc (sizeof (O65Data));
+
+    /* Initialize the fields as needed */
+    D->Options      = AUTO_COLLECTION_INITIALIZER;
+    D->Text         = 0;
+    D->Data         = 0;
+    D->TextReloc    = AUTO_COLLECTION_INITIALIZER;
+    D->DataReloc    = AUTO_COLLECTION_INITIALIZER;
+    D->Imports      = AUTO_COLLECTION_INITIALIZER;
+    D->Exports      = AUTO_COLLECTION_INITIALIZER;
+
+    /* Return the new struct */
+    return D;
+}
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+static unsigned long ReadO65Size (FILE* F, const O65Header* H)
+/* Read a size variable (16 or 32 bit, depending on the mode word in the
+ * header) from the o65 file.
+ */
+{
+    switch (H->mode & O65_SIZE_MASK) {
+        case O65_SIZE_32BIT:    return Read32 (F);
+        case O65_SIZE_16BIT:    return Read16 (F);
+        default:                Internal ("Invalid size field value in o65 header");
+    }
+}
+
+
+
+static void ReadO65Header (FILE* F, O65Header* H)
+/* Read an o65 header from the given file. The function will call Error if
+ * something is wrong.
+ */
+{
+    static const char Magic[3] = {
+        O65_MAGIC_0, O65_MAGIC_1, O65_MAGIC_2   /* "o65" */
+    };
+
+    /* Read the marker and check it */
+    ReadData (F, H->marker, sizeof (H->marker));
+    if (H->marker[0] != O65_MARKER_0 || H->marker[1] != O65_MARKER_1) {
+        Error ("Not an o65 object file: Invalid marker %02X %02X",
+               H->marker[0], H->marker[1]);
+    }
+
+    /* Read the magic and check it */
+    ReadData (F, H->magic, sizeof (H->magic));
+    if (memcmp (H->magic, Magic, sizeof (H->magic)) != 0) {
+        Error ("Not an o65 object file: Invalid magic %02X %02X %02X",
+               H->magic[0], H->magic[1], H->magic[2]);
+    }
+
+    /* Read the version number and check it */
+    H->version = Read8 (F);
+    if (H->version != O65_VERSION) {
+        Error ("Invalid o65 version number: %02X", H->version);
+    }
+
+    /* Read the mode word */
+    H->mode = Read16 (F);
+
+    /* Read the remainder of the header */
+    H->tbase = ReadO65Size (F, H);
+    H->tlen  = ReadO65Size (F, H);
+    H->dbase = ReadO65Size (F, H);
+    H->dlen  = ReadO65Size (F, H);
+    H->bbase = ReadO65Size (F, H);
+    H->blen  = ReadO65Size (F, H);
+    H->zbase = ReadO65Size (F, H);
+    H->zlen  = ReadO65Size (F, H);
+    H->stack = ReadO65Size (F, H);
+}
+
+
+
+static O65Option* ReadO65Option (FILE* F)
+/* Read the next O65 option from the given file. The option is stored into a
+ * dynamically allocated O65Option struct which is returned. On end of options,
+ * NULL is returned. On error, Error is called which terminates the program.
+ */
+{
+    O65Option* O;
+
+    /* Read the length of the option and bail out on end of options */
+    unsigned char Len = Read8 (F);
+    if (Len == 0) {
+        return 0;
+    }
+
+    /* Allocate a new O65Option structure of the needed size */
+    O = xmalloc (sizeof (*O) - sizeof (O->Data) + Len - 2);
+
+    /* Assign the length and read the remaining option data */
+    O->Len  = Len;
+    O->Type = Read8 (F);
+    ReadData (F, O->Data, Len - 2);
+
+    /* Return the new struct */
+    return O;
+}
+
+
+
+static O65Import* ReadO65Import (FILE* F)
+/* Read an o65 import from the file */
+{
+    O65Import* I;
+
+    /* Allow identifiers up to 511 bytes */
+    char Buf[512];
+
+    /* Read the identifier */
+    unsigned Len = 0;
+    char C;
+    do {
+        C = Read8 (F);
+        if (Len >= sizeof (Buf)) {
+            Error ("Imported identifier exceeds maximum size (%u)", sizeof (Buf));
+        }
+        Buf[Len++] = C;
+    } while (C != '\0');
+
+    /* Allocate an import structure and initialize it */
+    I = xmalloc (sizeof (*I) - sizeof (I->Name) + Len);
+    memcpy (I->Name, Buf, Len);
+
+    /* Return the new struct */
+    return I;
+}
+
+
+
+static void ReadO65RelocInfo (FILE* F, const O65Data* D, Collection* Reloc)
+/* Read relocation data for one segment */
+{
+    /* Relocation starts at (start address - 1) */
+    unsigned long Offs = (unsigned long) -1L;
+
+    while (1) {
+
+        O65Reloc* R;
+
+        /* Read the next relocation offset */
+        unsigned char C = Read8 (F);
+        if (C == 0) {
+            /* End of relocation table */
+            break;
+        }
+
+        /* Create a new relocation entry */
+        R = xmalloc (sizeof (*R));
+
+        /* Handle overflow bytes */
+        while (C == 0xFF) {
+            Offs += 0xFE;
+            C = Read8 (F);
+        }
+
+        /* Calculate the final offset */
+        R->Offs = (Offs += C);
+
+        /* Read typebyte and segment id */
+        C = Read8 (F);
+        R->Type   = (C & O65_RTYPE_MASK);
+        R->SegID  = (C & O65_SEGID_MASK);
+
+        /* Read an additional relocation value if there is one */
+        R->SymIdx = (R->SegID == O65_SEGID_UNDEF)? ReadO65Size (F, &D->Header) : 0;
+        switch (R->Type) {
+
+            case O65_RTYPE_HIGH:
+                if ((D->Header.mode & O65_RELOC_MASK) == O65_RELOC_BYTE) {
+                    /* Low byte follows */
+                    R->Val = Read8 (F);
+                } else {
+                    /* Low byte is zero */
+                    R->Val = 0;
+                }
+                break;
+
+            case O65_RTYPE_SEG:
+                /* Low 16 byte of the segment address follow */
+                R->Val = Read16 (F);
+                break;
+
+            default:
+                R->Val = 0;
+                break;
+        }
+
+        /* Insert this relocation entry into the collection */
+        CollAppend (Reloc, R);
+    }
+}
+
+
+
+static O65Export* ReadO65Export (FILE* F, const O65Header* H)
+/* Read an o65 export from the file */
+{
+    O65Export* E;
+
+    /* Allow identifiers up to 511 bytes */
+    char Buf[512];
+
+    /* Read the identifier */
+    unsigned Len = 0;
+    char C;
+    do {
+        C = Read8 (F);
+        if (Len >= sizeof (Buf)) {
+            Error ("Exported identifier exceeds maximum size (%u)", sizeof (Buf));
+        }
+        Buf[Len++] = C;
+    } while (C != '\0');
+
+    /* Allocate an export structure and initialize it */
+    E = xmalloc (sizeof (*E) - sizeof (E->Name) + Len);
+    memcpy (E->Name, Buf, Len);
+    E->SegID = Read8 (F);
+    E->Val   = ReadO65Size (F, H);
+
+    /* Return the new struct */
+    return E;
+}
+
+
+
+static O65Data* ReadO65Data (FILE* F)
+/* Read a complete o65 file into dynamically allocated memory and return the
+ * created O65Data struct.
+ */
+{
+    unsigned long Count;
+    O65Option* O;
+
+    /* Create the struct we're going to return */
+    O65Data* D = NewO65Data ();
+
+    /* Read the header */
+    ReadO65Header (F, &D->Header);
+
+    /* Read the options */
+    while ((O = ReadO65Option (F)) != 0) {
+        CollAppend (&D->Options, O);
+    }
+
+    /* Allocate space for the text segment and read it */
+    D->Text = xmalloc (D->Header.tlen);
+    ReadData (F, D->Text, D->Header.tlen);
+
+    /* Allocate space for the data segment and read it */
+    D->Data = xmalloc (D->Header.dlen);
+    ReadData (F, D->Data, D->Header.dlen);
+
+    /* Read the undefined references list */
+    Count = ReadO65Size (F, &D->Header);
+    while (Count--) {
+        CollAppend (&D->Imports, ReadO65Import (F));
+    }
+
+    /* Read the relocation tables for text and data segment */
+    ReadO65RelocInfo (F, D, &D->TextReloc);
+    ReadO65RelocInfo (F, D, &D->DataReloc);
+
+    /* Read the exported globals list */
+    Count = ReadO65Size (F, &D->Header);
+    while (Count--) {
+        CollAppend (&D->Exports, ReadO65Export (F, &D->Header));
+    }
+
+    /* Return the o65 data read from the file */
+    return D;
+}
+
+
+
+O65Data* ReadO65File (const char* Name)
+/* Read a complete o65 file into dynamically allocated memory and return the
+ * created O65Data struct.
+ */
+{
+    O65Data* D;
+
+    /* Open the o65 input file */
+    FILE* F = fopen (Name, "rb");
+    if (F == 0) {
+        Error ("Cannot open `%s': %s", Name, strerror (errno));
+    }
+
+    /* Read the file data */
+    D = ReadO65Data (F);
+
+    /* Close the input file. Ignore errors since we were only reading */
+    fclose (F);
+
+    /* Return the data read */
+    return D;
+}
+
+
+
diff --git a/src/co65/o65.h b/src/co65/o65.h
new file mode 100644 (file)
index 0000000..4cb395f
--- /dev/null
@@ -0,0 +1,222 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                  o65.h                                   */
+/*                                                                           */
+/*               Definitions and code for the o65 file format                */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2002-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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* This files exports structures and constants to handle the o65 relocatable
+ * file format as defined by Andre Fachat. See the original document under
+ *
+ *      http://www.6502.org/users/andre/o65/fileformat.html
+ *
+ * for more information.
+ */
+
+
+
+#ifndef _O65_H
+#define _O65_H
+
+
+
+/* common */
+#include "coll.h"
+
+
+
+/*****************************************************************************/
+/*                                  Defines                                  */
+/*****************************************************************************/
+
+
+
+/* Define a structure for the o65 file header */
+typedef struct {
+    char            marker[2];  /* Non-C64 marker */
+    char            magic[3];   /* o65 magic */
+    char            version;   /* Version number */
+    unsigned        mode;       /* Mode word */
+    unsigned long   tbase;      /* Original text (code) segment address */
+    unsigned long   tlen;       /* Size of text (code) segment */
+    unsigned long   dbase;      /* Original data segment address */
+    unsigned long   dlen;       /* Size of data segment */
+    unsigned long   bbase;      /* Original bss segment address */
+    unsigned long   blen;       /* Size of bss segment */
+    unsigned long   zbase;      /* Original zp segment address */
+    unsigned long   zlen;       /* Size of zp segment */
+    unsigned long   stack;      /* Stacksize needed */
+} O65Header;
+
+/* o65 option */
+typedef struct {
+    unsigned char   Len;        /* Option length */
+    unsigned char   Type;       /* Option type */
+    unsigned char   Data[1];    /* Option data (dynamically allocated) */
+} O65Option;
+
+/* o65 relocation entry */
+typedef struct {
+    unsigned long   Offs;       /* Offset in segment */
+    unsigned char   Type;       /* Relocation type */
+    unsigned char   SegID;      /* Segment ID */
+    unsigned        Val;        /* Any offset value needed for relocation */
+    unsigned long   SymIdx;     /* Index into list of imported symbols */
+} O65Reloc;
+
+/* o65 import */
+typedef struct {
+    char            Name[1];    /* Name of the import (dynamically allocated) */
+} O65Import;
+
+/* o65 export */
+typedef struct {
+    unsigned char   SegID;      /* Segment ID */
+    unsigned long   Val;        /* Relocation value */
+    char            Name[1];    /* Name of the export (dynamically allocated) */
+} O65Export;
+
+/* Complete o65 file data */
+typedef struct {
+    O65Header       Header;     /* File header */
+    Collection      Options;    /* O65 options */
+    unsigned char*  Text;       /* Text segment data (unrelocated) */
+    unsigned char*  Data;       /* Data segment data (unrelocated) */
+    Collection      TextReloc;  /* Relocation entries for the text segment */
+    Collection      DataReloc;  /* Relocation entries for the data segment */
+    Collection      Imports;    /* Imported symbols */
+    Collection      Exports;    /* Exported symbols */
+} O65Data;
+
+
+
+/* Marker, magic and version number */
+#define O65_MARKER_0            0x01
+#define O65_MARKER_1            0x00
+#define O65_MAGIC_0             0x6F    /* 'o' */
+#define O65_MAGIC_1             0x36    /* '6' */
+#define O65_MAGIC_2             0x35    /* '5' */
+#define O65_VERSION             0x00
+
+/* Defines for the mode word */
+#define O65_CPU_65816           0x8000         /* Executable is for 65816 */
+#define O65_CPU_6502            0x0000  /* Executable is for the 6502 */
+#define O65_CPU_MASK            0x8000  /* Mask to extract CPU type */
+
+#define O65_RELOC_PAGE          0x4000  /* Page wise relocation */
+#define O65_RELOC_BYTE          0x0000  /* Byte wise relocation */
+#define O65_RELOC_MASK          0x4000  /* Mask to extract relocation type */
+
+#define O65_SIZE_32BIT          0x2000         /* All size words are 32bit */
+#define O65_SIZE_16BIT          0x0000  /* All size words are 16bit */
+#define O65_SIZE_MASK           0x2000  /* Mask to extract size */
+
+#define O65_FTYPE_OBJ           0x1000  /* Object file */
+#define O65_FTYPE_EXE           0x0000  /* Executable file */
+#define O65_FTYPE_MASK          0x1000  /* Mask to extract type */
+
+#define O65_ADDR_SIMPLE         0x0800  /* Simple addressing */
+#define O65_ADDR_DEFAULT        0x0000  /* Default addressing */
+#define O65_ADDR_MASK           0x0800  /* Mask to extract addressing */
+
+#define O65_ALIGN_1             0x0000  /* Bytewise alignment */
+#define O65_ALIGN_2             0x0001  /* Align words */
+#define O65_ALIGN_4             0x0002  /* Align longwords */
+#define O65_ALIGN_256           0x0003  /* Align pages (256 bytes) */
+#define O65_ALIGN_MASK          0x0003  /* Mask to extract alignment */
+
+/* The mode word as generated by the ld65 linker */
+#define O65_MODE_CC65           (O65_CPU_6502    |      \
+                                 O65_RELOC_BYTE  |      \
+                                 O65_SIZE_16BIT  |      \
+                                 O65_FTYPE_EXE   |      \
+                                 O65_ADDR_SIMPLE |      \
+                                 O65_ALIGN_1)
+
+/* The four o65 segment types. */
+#define O65_SEGID_UNDEF                0x00
+#define O65_SEGID_ABS           0x01
+#define O65_SEGID_TEXT                 0x02
+#define O65_SEGID_DATA          0x03
+#define O65_SEGID_BSS           0x04
+#define O65_SEGID_ZP            0x05
+#define O65_SEGID_MASK          0x07
+
+/* Relocation type codes */
+#define O65_RTYPE_WORD          0x80
+#define O65_RTYPE_HIGH          0x40
+#define O65_RTYPE_LOW           0x20
+#define O65_RTYPE_SEGADDR       0xC0
+#define O65_RTYPE_SEG           0xA0
+#define O65_RTYPE_MASK          0xE0
+
+/* Segment IDs */
+#define O65_SEGID_UNDEF         0x00
+#define O65_SEGID_ABS           0x01
+#define O65_SEGID_TEXT          0x02
+#define O65_SEGID_DATA          0x03
+#define O65_SEGID_BSS           0x04
+#define O65_SEGID_ZP            0x05
+#define O65_SEGID_MASK          0x07
+
+/* Option tags */
+#define O65_OPT_FILENAME        0
+#define O65_OPT_OS                     1
+#define O65_OPT_ASM            2
+#define O65_OPT_AUTHOR         3
+#define O65_OPT_TIMESTAMP      4
+
+/* Operating system codes for O65_OPT_OS */
+#define O65_OS_OSA65           1
+#define O65_OS_LUNIX           2
+#define O65_OS_CC65_MODULE      3
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+O65Data* ReadO65File (const char* Name);
+/* Read a complete o65 file into dynamically allocated memory and return the
+ * created O65Data struct.
+ */
+
+
+
+/* End of o65.h */
+#endif
+
+
+
+