]> git.sur5r.net Git - cc65/blobdiff - src/ld65/span.c
Add translation from PETSCII to screen codes.
[cc65] / src / ld65 / span.c
index da8cd83dd609bd02e5d8578a12f7084e4f126047..498ab762ada2e9cac0729cb4af36841a70f5b971 100644 (file)
@@ -34,7 +34,7 @@
 
 
 /* common */
-#include "attrib.h"
+#include "gentype.h"
 #include "xmalloc.h"
 
 /* ld65 */
@@ -42,6 +42,7 @@
 #include "objdata.h"
 #include "segments.h"
 #include "span.h"
+#include "tpool.h"
 
 
 
 
 /* Definition of a span */
 struct Span {
-    unsigned           Id;             /* Id of the span */
+    unsigned            Id;             /* Id of the span */
     unsigned            Sec;            /* Section id of this span */
     unsigned long       Offs;           /* Offset of span within segment */
     unsigned long       Size;           /* Size of span */
+    unsigned            Type;           /* Generic type of the data */
 };
 
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
 
-static Span* NewSpan (unsigned Id, unsigned Sec, unsigned long Offs, unsigned long Size)
+static Span* NewSpan (unsigned Id)
 /* Create and return a new span */
 {
     /* Allocate memory */
-    Span* S = xmalloc (sizeof (*S));
+    Span* S = xmalloc (sizeof (Span));
 
-    /* Initialize the fields */
+    /* Initialize the fields as necessary */
     S->Id       = Id;
-    S->Sec      = Sec;
-    S->Offs     = Offs;
-    S->Size     = Size;
 
     /* Return the result */
     return S;
@@ -85,48 +84,83 @@ static Span* NewSpan (unsigned Id, unsigned Sec, unsigned long Offs, unsigned lo
 
 
 
-Span* ReadSpan (FILE* F, ObjData* O attribute ((unused)), unsigned Id)
+Span* ReadSpan (FILE* F, ObjData* O, unsigned Id)
 /* Read a Span from a file and return it */
 {
-    /* Create a new Span and return it */
-    unsigned SecId     = ReadVar (F);
-    unsigned long Offs = ReadVar (F);
-    unsigned Size      = ReadVar (F);
-    return NewSpan (Id, SecId, Offs, Size);
+    unsigned Type;
+
+    /* Create a new Span and initialize it */
+    Span* S = NewSpan (Id);
+    S->Sec  = ReadVar (F);
+    S->Offs = ReadVar (F);
+    S->Size = ReadVar (F);
+
+    /* Read the type. An id of zero means an empty string (no need to check) */
+    Type    = ReadVar (F);
+    if (Type == 0) {
+        S->Type = INVALID_TYPE_ID;
+    } else {
+        S->Type = GetTypeId (GetObjString (O, Type));
+    }
+
+    /* Return the new span */
+    return S;
 }
 
 
 
-void ReadSpanList (Collection* Spans, FILE* F, ObjData* O)
-/* Read a list of span ids from a file and return the spans for the ids */
+unsigned* ReadSpanList (FILE* F)
+/* Read a list of span ids from a file. The list is returned as an array of
+** unsigneds, the first being the number of spans (never zero) followed by
+** the span ids. If the number of spans is zero, NULL is returned.
+*/
 {
+    unsigned* Spans;
+
     /* First is number of Spans */
     unsigned Count = ReadVar (F);
+    if (Count == 0) {
+        return 0;
+    }
 
-    /* Preallocate enough entries in the collection */
-    CollGrow (Spans, Count);
+    /* Allocate memory for the list and set the count */
+    Spans  = xmalloc ((Count + 1) * sizeof (*Spans));
+    *Spans = Count;
 
     /* Read the spans and add them */
-    while (Count--) {
-        CollAppend (Spans, CollAt (&O->Spans, ReadVar (F)));
+    while (Count) {
+        Spans[Count] = ReadVar (F);
+        --Count;
     }
+
+    /* Return the list */
+    return Spans;
 }
 
 
 
-void FreeSpan (Span* S)
-/* Free a span structure */
+unsigned* DupSpanList (const unsigned* S)
+/* Duplicate a span list */
 {
-    /* Just free the structure */
-    xfree (S);
+    unsigned Size;
+
+    /* The list may be empty */
+    if (S == 0) {
+        return 0;
+    }
+
+    /* Allocate memory, copy and return the new list */
+    Size = (*S + 1) * sizeof (*S);
+    return memcpy (xmalloc (Size), S, Size);
 }
 
 
 
-unsigned SpanId (const struct ObjData* O, const Span* S)
-/* Return the global id of a span */
+void FreeSpan (Span* S)
+/* Free a span structure */
 {
-    return O->SpanBaseId + S->Id;
+    /* Just free the structure */
+    xfree (S);
 }
 
 
@@ -151,10 +185,30 @@ unsigned SpanCount (void)
 
 
 
+void PrintDbgSpanList (FILE* F, const ObjData* O, const unsigned* List)
+/* Output a string ",span=x[+y...]" for the given list. If the list is empty
+** or NULL, output nothing. This is a helper function for other modules to
+** print a list of spans read by ReadSpanList to the debug info file.
+*/
+{
+    if (List && *List) {
+        unsigned I;
+        const char* Format = ",span=%u";
+        for (I = 0; I < *List; ++I) {
+            fprintf (F, Format, O->SpanBaseId + List[I+1]);
+            Format = "+%u";
+        }
+    }
+}
+
+
+
 void PrintDbgSpans (FILE* F)
 /* Output the spans to a debug info file */
 {
     unsigned I, J;
+    StrBuf SpanType = STATIC_STRBUF_INITIALIZER;
+
 
     /* Walk over all object files */
     for (I = 0; I < CollCount (&ObjDataList); ++I) {
@@ -166,20 +220,28 @@ void PrintDbgSpans (FILE* F)
         for (J = 0; J < CollCount (&O->Spans); ++J) {
 
             /* Get this span */
-            Span* S = CollAtUnchecked (&O->Spans, J);
+            const Span* S = CollAtUnchecked (&O->Spans, J);
 
             /* Get the section for this span */
             const Section* Sec = GetObjSection (O, S->Sec);
 
             /* Output the data */
-            fprintf (F, "span\tid=%u,seg=%u,start=%lu,size=%lu\n",
+            fprintf (F, "span\tid=%u,seg=%u,start=%lu,size=%lu",
                      O->SpanBaseId + S->Id,
                      Sec->Seg->Id,
                      Sec->Offs + S->Offs,
                      S->Size);
-        }
-    }
-}
 
+            /* If we have a type, add it */
+            if (S->Type != INVALID_TYPE_ID) {
+                fprintf (F, ",type=%u", S->Type);
+            }
 
+            /* Terminate the output line */
+            fputc ('\n', F);
+        }
+    }
 
+    /* Free the string buffer */
+    SB_Done (&SpanType);
+}