]> git.sur5r.net Git - cc65/blobdiff - src/co65/convert.c
The opcode for BS should be 0x0C.
[cc65] / src / co65 / convert.c
index ed9ff15a1cfcc366273f4b276ea78589a2ed9580..af036ebf757b6fd328058d90efda94f1ee959cac 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2003      Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2003-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -54,7 +54,7 @@
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
@@ -101,49 +101,6 @@ static void SetupSegLabels (FILE* F)
 
 
 
-static void ConvertImports (FILE* F, const O65Data* D)
-/* Convert the imports */
-{
-    unsigned I;
-
-    if (CollCount (&D->Imports) > 0) {
-        for (I = 0; I < CollCount (&D->Imports); ++I) {
-
-            /* Get the next import */
-            const O65Import* Import = CollConstAt (&D->Imports, I);
-
-            /* Import it by name */
-            fprintf (F, ".import\t%s\n", Import->Name);
-        }
-        fprintf (F, "\n");
-    }
-}
-
-
-
-static void ConvertExports (FILE* F, const O65Data* D)
-/* Convert the exports */
-{
-    unsigned I;
-
-    if (CollCount (&D->Exports) > 0) {
-        for (I = 0; I < CollCount (&D->Exports); ++I) {
-
-            /* Get the next import */
-            const O65Export* Export = CollConstAt (&D->Exports, I);
-
-            /* First define it */
-            fprintf (F, "%s = XXX\n", Export->Name);    /* ### */
-
-            /* Then export it by name */
-            fprintf (F, ".export\t%s\n", Export->Name);
-        }
-        fprintf (F, "\n");
-    }
-}
-
-
-
 static const char* LabelPlusOffs (const char* Label, long Offs)
 /* Generate "Label+xxx" in a static buffer and return a pointer to the buffer */
 {
@@ -154,19 +111,29 @@ static const char* LabelPlusOffs (const char* Label, long Offs)
 
 
 
-static const char* RelocExpr (const O65Data* D, const O65Reloc* R, unsigned long Val)
-/* Generate the segment relative relocation expression */
+static const char* RelocExpr (const O65Data* D, unsigned char SegID,
+                              unsigned long Val, const O65Reloc* R)
+/* Generate the segment relative relocation expression. R is only used if the
+** expression contains am import, and may be NULL if this is an error (which
+** is then flagged).
+*/
 {
     const O65Import* Import;
 
-    switch (R->SegID) {
+    switch (SegID) {
 
         case O65_SEGID_UNDEF:
-            if (R->SymIdx >= CollCount (&D->Imports)) {
-                Error ("Import index out of range (input file corrupt)");
+            if (R) {
+                if (R->SymIdx >= CollCount (&D->Imports)) {
+                    Error ("Import index out of range (input file corrupt)");
+                }
+                Import = CollConstAt (&D->Imports, R->SymIdx);
+                return LabelPlusOffs (Import->Name, Val);
+            } else {
+                Error ("Relocation references an import which is not allowed here");
+                return 0;
             }
-            Import = CollConstAt (&D->Imports, R->SymIdx);
-            return LabelPlusOffs (Import->Name, Val);
+            break;
 
         case O65_SEGID_TEXT:
             return LabelPlusOffs (CodeLabel, Val - D->Header.tbase);
@@ -193,6 +160,51 @@ static const char* RelocExpr (const O65Data* D, const O65Reloc* R, unsigned long
 
 
 
+static void ConvertImports (FILE* F, const O65Data* D)
+/* Convert the imports */
+{
+    unsigned I;
+
+    if (CollCount (&D->Imports) > 0) {
+        for (I = 0; I < CollCount (&D->Imports); ++I) {
+
+            /* Get the next import */
+            const O65Import* Import = CollConstAt (&D->Imports, I);
+
+            /* Import it by name */
+            fprintf (F, ".import\t%s\n", Import->Name);
+        }
+        fprintf (F, "\n");
+    }
+}
+
+
+
+static void ConvertExports (FILE* F, const O65Data* D)
+/* Convert the exports */
+{
+    unsigned I;
+
+    if (CollCount (&D->Exports) > 0) {
+        for (I = 0; I < CollCount (&D->Exports); ++I) {
+
+            /* Get the next import */
+            const O65Export* Export = CollConstAt (&D->Exports, I);
+
+            /* First define it */
+            fprintf (F, "%s = %s\n",
+                     Export->Name,
+                     RelocExpr (D, Export->SegID, Export->Val, 0));
+
+            /* Then export it by name */
+            fprintf (F, ".export\t%s\n", Export->Name);
+        }
+        fprintf (F, "\n");
+    }
+}
+
+
+
 static void ConvertSeg (FILE* F, const O65Data* D, const Collection* Relocs,
                         const unsigned char* Data, unsigned long Size)
 /* Convert one segment */
@@ -222,18 +234,18 @@ static void ConvertSeg (FILE* F, const O65Data* D, const Collection* Relocs,
                     } else {
                         Val = (Data[Byte+1] << 8) + Data[Byte];
                         Byte += 2;
-                        fprintf (F, "\t.word\t%s\n", RelocExpr (D, R, Val));
+                        fprintf (F, "\t.word\t%s\n", RelocExpr (D, R->SegID, Val, R));
                     }
                     break;
 
                 case O65_RTYPE_HIGH:
                     Val = (Data[Byte++] << 8) + R->Val;
-                    fprintf (F, "\t.byte\t>(%s)\n", RelocExpr (D, R, Val));
+                    fprintf (F, "\t.byte\t>(%s)\n", RelocExpr (D, R->SegID, Val, R));
                     break;
 
                 case O65_RTYPE_LOW:
                     Val = Data[Byte++];
-                    fprintf (F, "\t.byte\t<(%s)\n", RelocExpr (D, R, Val));
+                    fprintf (F, "\t.byte\t<(%s)\n", RelocExpr (D, R->SegID, Val, R));
                     break;
 
                 case O65_RTYPE_SEGADDR:
@@ -245,7 +257,7 @@ static void ConvertSeg (FILE* F, const O65Data* D, const Collection* Relocs,
                               (((unsigned long) Data[Byte+0]) <<  0) +
                               R->Val;
                         Byte += 3;
-                        fprintf (F, "\t.faraddr\t%s\n", RelocExpr (D, R, Val));
+                        fprintf (F, "\t.faraddr\t%s\n", RelocExpr (D, R->SegID, Val, R));
                     }
                     break;
 
@@ -334,15 +346,15 @@ static void ConvertZeropageSeg (FILE* F, const O65Data* D)
 
     if (Model == O65_MODEL_CC65_MODULE) {
         /* o65 files of type cc65-module are linked together with a definition
-         * file for the zero page, but the zero page is not allocated in the
-         * module itself, but the locations are mapped to the zp locations of
-         * the main file.
-         */
+        ** file for the zero page, but the zero page is not allocated in the
+        ** module itself, but the locations are mapped to the zp locations of
+        ** the main file.
+        */
         fprintf (F, ".import\t__ZP_START__\t\t; Linker generated symbol\n");
         fprintf (F, "%s = __ZP_START__\n", ZeropageLabel);
     } else {
         /* Header */
-        fprintf (F, ".segment\t\"%s\", zeropage\n%s:\n", ZeropageSeg, ZeropageLabel);
+        fprintf (F, ".segment\t\"%s\": zeropage\n%s:\n", ZeropageSeg, ZeropageLabel);
 
         /* Segment data */
         fprintf (F, "\t.res\t%lu\n", D->Header.zlen);
@@ -352,7 +364,7 @@ static void ConvertZeropageSeg (FILE* F, const O65Data* D)
 
 
 
-void Convert (const O65Data* D, const char* OutputFile)
+void Convert (const O65Data* D)
 /* Convert the o65 file in D using the given output file. */
 {
     FILE*       F;
@@ -360,8 +372,8 @@ void Convert (const O65Data* D, const char* OutputFile)
     char*       Author = 0;
 
     /* For now, we do only accept o65 files generated by the ld65 linker which
-     * have a specific format.
-     */
+    ** have a specific format.
+    */
     if (!Debug && D->Header.mode != O65_MODE_CC65) {
         Error ("Cannot convert o65 files of this type");
     }
@@ -370,9 +382,9 @@ void Convert (const O65Data* D, const char* OutputFile)
     PrintO65Stats (D);
 
     /* Walk through the options and print them if verbose mode is enabled.
-     * Check for a os=cc65 option and bail out if we didn't find one (for
-     * now - later we switch to special handling).
-     */
+    ** Check for a os=cc65 option and bail out if we didn't find one (for
+    ** now - later we switch to special handling).
+    */
     for (I = 0; I < CollCount (&D->Options); ++I) {
 
         /* Get the next option */
@@ -396,7 +408,7 @@ void Convert (const O65Data* D, const char* OutputFile)
                         case O65_OS_CC65_MODULE:
                             if (Model != O65_MODEL_NONE &&
                                 Model != O65_MODEL_CC65_MODULE) {
-                                Warning ("Wrong o65 model");
+                                Warning ("Wrong o65 model for input file specified");
                             } else {
                                 Model = O65_MODEL_CC65_MODULE;
                             }
@@ -430,24 +442,28 @@ void Convert (const O65Data* D, const char* OutputFile)
         }
     }
 
+    /* If we shouldn't generate output, we're done here */
+    if (NoOutput) {
+        return;
+    }
+
     /* Open the output file */
-    F = fopen (OutputFile, "wb");
+    F = fopen (OutputName, "w");
     if (F == 0) {
-        Error ("Cannot open `%s': %s", OutputFile, strerror (errno));
+        Error ("Cannot open `%s': %s", OutputName, strerror (errno));
     }
 
     /* Create a header */
-    fprintf (F, ";\n; File generated by co65 v %u.%u.%u using model `%s'\n;\n",
-             VER_MAJOR, VER_MINOR, VER_PATCH, GetModelName (Model));
+    fprintf (F, ";\n; File generated by co65 v %s using model `%s'\n;\n",
+             GetVersionAsString (), GetModelName (Model));
 
     /* Select the CPU */
     if ((D->Header.mode & O65_CPU_MASK) == O65_CPU_65816) {
-       fprintf (F, ".p816\n");
+        fprintf (F, ".p816\n");
     }
 
     /* Object file options */
-    fprintf (F, ".fopt\t\tcompiler,\"co65 v %u.%u.%u\"\n",
-             VER_MAJOR, VER_MINOR, VER_PATCH);
+    fprintf (F, ".fopt\t\tcompiler,\"co65 v %s\"\n", GetVersionAsString ());
     if (Author) {
         fprintf (F, ".fopt\t\tauthor, \"%s\"\n", Author);
         xfree (Author);
@@ -486,6 +502,3 @@ void Convert (const O65Data* D, const char* OutputFile)
     fprintf (F, ".end\n");
     fclose (F);
 }
-
-
-