]> git.sur5r.net Git - cc65/blobdiff - src/da65/output.c
Save two bytes by a small code change.
[cc65] / src / da65 / output.c
index a655b605f6465bae1b2098bf6567d9efcc61270b..9a20b55f84df3c87e242f6cffea219c78ae0901f 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2000-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
+#include <ctype.h>
 #include <errno.h>
 
+/* common */
+#include "addrsize.h"
+#include "cpu.h"
+#include "version.h"
+
 /* da65 */
 #include "code.h"
 #include "error.h"
@@ -54,6 +60,9 @@
 
 static FILE*   F       = 0;            /* Output stream */
 static unsigned        Col     = 1;            /* Current column */
+static unsigned Line           = 0;            /* Current line on page */
+static unsigned Page   = 1;            /* Current output page */
+
 
 
 /*****************************************************************************/
@@ -62,14 +71,39 @@ static unsigned     Col     = 1;            /* Current column */
 
 
 
+static void PageHeader (void)
+/* Print a page header */
+{
+    fprintf (F,
+                    "; da65 V%s - (C) Copyright 2000-2009,  Ullrich von Bassewitz\n"
+             "; Created:    %s\n"
+            "; Input file: %s\n"
+            "; Page:       %u\n\n",
+                    GetVersionAsString (),
+             Now,
+            InFile,
+            Page);
+}
+
+
+
 void OpenOutput (const char* Name)
 /* Open the given file for output */
 {
-    /* Open the output file */
-    F = fopen (Name, "w");
-    if (F == 0) {
-       Error ("Cannot open `%s': %s", Name, strerror (errno));
+    /* If we have a name given, open the output file, otherwise use stdout */
+    if (Name != 0) {
+        F = fopen (Name, "w");
+        if (F == 0) {
+            Error ("Cannot open `%s': %s", Name, strerror (errno));
+        }
+    } else {
+        F = stdout;
     }
+
+    /* Output the header and initialize stuff */
+    PageHeader ();
+    Line = 5;
+    Col  = 1;
 }
 
 
@@ -77,7 +111,7 @@ void OpenOutput (const char* Name)
 void CloseOutput (void)
 /* Close the output file */
 {
-    if (fclose (F) != 0) {
+    if (F != stdout && fclose (F) != 0) {
        Error ("Error closing output file: %s", strerror (errno));
     }
 }
@@ -87,7 +121,7 @@ void CloseOutput (void)
 void Output (const char* Format, ...)
 /* Write to the output file */
 {
-    if (Pass > 1) {
+    if (Pass == PassCount) {
        va_list ap;
        va_start (ap, Format);
        Col += vfprintf (F, Format, ap);
@@ -100,7 +134,7 @@ void Output (const char* Format, ...)
 void Indent (unsigned N)
 /* Make sure the current line column is at position N (zero based) */
 {
-    if (Pass > 1) {
+    if (Pass == PassCount) {
        while (Col < N) {
            fputc (' ', F);
            ++Col;
@@ -113,9 +147,17 @@ void Indent (unsigned N)
 void LineFeed (void)
 /* Add a linefeed to the output file */
 {
-    if (Pass > 1) {
+    if (Pass == PassCount) {
        fputc ('\n', F);
-       Col = 1;
+               if (PageLength > 0 && ++Line >= PageLength) {
+           if (FormFeeds) {
+               fputc ('\f', F);
+           }
+           ++Page;
+           PageHeader ();
+           Line = 5;
+       }
+       Col = 1;
     }
 }
 
@@ -125,23 +167,159 @@ void DefLabel (const char* Name)
 /* Define a label with the given name */
 {
     Output ("%s:", Name);
+    /* If the label is longer than the configured maximum, or if it runs into
+     * the opcode column, start a new line.
+     */
+    if (Col > LBreak+2 || Col > MCol) {
+       LineFeed ();
+    }
+}
+
+
+
+void DefForward (const char* Name, const char* Comment, unsigned Offs)
+/* Define a label as "* + x", where x is the offset relative to the
+ * current PC.
+ */
+{
+    if (Pass == PassCount) {
+        /* Flush existing output if necessary */
+        if (Col > 1) {
+            LineFeed ();
+        }
+
+        /* Output the forward definition */
+        Output ("%s", Name);
+        Indent (ACol);
+        if (UseHexOffs) {
+            Output (":= * + $%04X", Offs);
+        } else {
+            Output (":= * + %u", Offs);
+        }
+        if (Comment) {
+            Indent (CCol);
+            Output ("; %s", Comment);
+        }
+        LineFeed ();
+    }
+}
+
+
+
+void DefConst (const char* Name, const char* Comment, unsigned Addr)
+/* Define an address constant */
+{
+    if (Pass == PassCount) {
+        Output ("%s", Name);
+        Indent (ACol);
+        Output (":= $%04X", Addr);
+        if (Comment) {
+            Indent (CCol);
+            Output ("; %s", Comment);
+        }
+        LineFeed ();
+    }
+}
+
+
+
+void StartSegment (const char* Name, unsigned AddrSize)
+/* Start a segment */
+{
+    if (Pass == PassCount) {
+        Output (".segment");
+        Indent (ACol);
+        if (AddrSize == ADDR_SIZE_DEFAULT) {
+            Output ("\"%s\"", Name);
+        } else {
+            Output ("\"%s\": %s", Name, AddrSizeToStr (AddrSize));
+        }
+        LineFeed ();
+    }
+}
+
+
+
+void DataByteLine (unsigned ByteCount)
+/* Output a line with bytes */
+{
+    unsigned I;
+
+    Indent (MCol);
+    Output (".byte");
+    Indent (ACol);
+    for (I = 0; I < ByteCount; ++I) {
+       if (I > 0) {
+           Output (",$%02X", CodeBuf[PC+I]);
+       } else {
+           Output ("$%02X", CodeBuf[PC+I]);
+       }
+    }
+    LineComment (PC, ByteCount);
     LineFeed ();
 }
 
 
 
-void OneDataByte (void)
-/* Output a .byte line with the current code byte */
+void DataDByteLine (unsigned ByteCount)
+/* Output a line with dbytes */
 {
-    unsigned char B = GetCodeByte ();
+    unsigned I;
+
+    Indent (MCol);
+    Output (".dbyt");
+    Indent (ACol);
+    for (I = 0; I < ByteCount; I += 2) {
+       if (I > 0) {
+                   Output (",$%04X", GetCodeDByte (PC+I));
+       } else {
+           Output ("$%04X", GetCodeDByte (PC+I));
+       }
+    }
+    LineComment (PC, ByteCount);
+    LineFeed ();
+}
 
-    if (Pass > 1) {
-       Indent (MIndent);
-       Output (".byte");
-       Indent (AIndent);
-       Output ("$%02X", B);
-       LineFeed ();
+
+
+void DataWordLine (unsigned ByteCount)
+/* Output a line with words */
+{
+    unsigned I;
+
+    Indent (MCol);
+    Output (".word");
+    Indent (ACol);
+    for (I = 0; I < ByteCount; I += 2) {
+       if (I > 0) {
+           Output (",$%04X", GetCodeWord (PC+I));
+       } else {
+           Output ("$%04X", GetCodeWord (PC+I));
+       }
+    }
+    LineComment (PC, ByteCount);
+    LineFeed ();
+}
+
+
+
+void DataDWordLine (unsigned ByteCount)
+/* Output a line with dwords */
+{
+    unsigned I;
+
+    Indent (MCol);
+    Output (".dword");
+    Indent (ACol);
+    for (I = 0; I < ByteCount; I += 4) {
+       if (I > 0) {
+           Output (",$%08lX", GetCodeDWord (PC+I));
+       } else {
+           Output ("$%08lX", GetCodeDWord (PC+I));
+       }
     }
+    LineComment (PC, ByteCount);
+    LineFeed ();
 }
 
 
@@ -149,10 +327,62 @@ void OneDataByte (void)
 void SeparatorLine (void)
 /* Print a separator line */
 {
-    Output ("; -------------------------------------------------------------------------");
+    if (Pass == PassCount && Comments >= 1) {
+       Output ("; ----------------------------------------------------------------------------");
+       LineFeed ();
+    }
+}
+
+
+
+void UserComment (const char* Comment)
+/* Output a comment line */
+{
+    Output ("; %s", Comment);
+    LineFeed ();
+}
+
+
+
+void LineComment (unsigned PC, unsigned Count)
+/* Add a line comment with the PC and data bytes */
+{
+    unsigned I;
+
+    if (Pass == PassCount && Comments >= 2) {
+       Indent (CCol);
+       Output ("; %04X", PC);
+       if (Comments >= 3) {
+           for (I = 0; I < Count; ++I) {
+               Output (" %02X", CodeBuf [PC+I]);
+           }
+           if (Comments >= 4) {
+               Indent (TCol);
+               for (I = 0; I < Count; ++I) {
+                   unsigned char C = CodeBuf [PC+I];
+                   if (!isprint (C)) {
+                       C = '.';
+                   }
+                   Output ("%c", C);
+               }
+           }
+       }
+    }
+}
+
+
+
+void OutputSettings (void)
+/* Output CPU and other settings */
+{
+    LineFeed ();
+    Indent (MCol);
+    Output (".setcpu");
+    Indent (ACol);
+    Output ("\"%s\"", CPUNames[CPU]);
+    LineFeed ();
     LineFeed ();
 }
 
 
 
-