]> git.sur5r.net Git - cc65/blob - src/ca65/span.c
Grow the Span collection before adding spans for the segments. This means that
[cc65] / src / ca65 / span.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                  span.c                                   */
4 /*                                                                           */
5 /*                      A span of data within a segment                      */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2003-2011, Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 /* common */
37 #include "xmalloc.h"
38
39 /* ca65 */
40 #include "objfile.h"
41 #include "segment.h"
42 #include "span.h"
43
44
45
46 /*****************************************************************************/
47 /*                                   Data                                    */
48 /*****************************************************************************/
49
50
51
52 /*****************************************************************************/
53 /*                                   Code                                    */
54 /*****************************************************************************/
55
56
57
58 static Span* NewSpan (Segment* Seg, unsigned long Start, unsigned long End)
59 /* Create a new span. The segment is set to Seg, Start and End are set to the
60  * current PC of the segment.
61  */
62 {
63     /* Allocate memory */
64     Span* S = xmalloc (sizeof (Span));
65
66     /* Initialize the struct */
67     S->Seg      = Seg;
68     S->Start    = Start;
69     S->End      = End;
70
71     /* Return the new struct */
72     return S;
73 }
74
75
76
77 static void FreeSpan (Span* S)
78 /* Free a span */
79 {
80     xfree (S);
81 }
82
83
84
85 void OpenSpans (Collection* Spans)
86 /* Open a list of spans for all existing segments to the given collection of
87  * spans. The currently active segment will be inserted first with all others
88  * following.
89  */
90 {
91     unsigned I;
92
93     /* Grow the Spans collection as necessary */
94     CollGrow (Spans, CollCount (&SegmentList));
95
96     /* Add the currently active segment */
97     CollAppend (Spans, NewSpan (ActiveSeg, ActiveSeg->PC, ActiveSeg->PC));
98
99     /* Walk through the segment list and add all other segments */
100     for (I = 0; I < CollCount (&SegmentList); ++I) {
101         Segment* Seg = CollAtUnchecked (&SegmentList, I);
102
103         /* Be sure to skip the active segment, since it was already added */
104         if (Seg != ActiveSeg) {
105             CollAppend (Spans, NewSpan (Seg, Seg->PC, Seg->PC));
106         }
107     }
108 }
109
110
111
112 void CloseSpans (Collection* Spans)
113 /* Close a list of spans. This will add new segments to the list, mark the end
114  * of existing ones, and remove empty spans from the list.
115  */
116 {
117     unsigned I, J;
118
119     /* Have new segments been added while the span list was open? */
120     for (I = CollCount (Spans); I < CollCount (&SegmentList); ++I) {
121
122         /* Add new spans if not empty */
123         Segment* S = CollAtUnchecked (&SegmentList, I);
124         if (S->PC == 0) {
125             /* Segment is empty */
126             continue;
127         }
128         CollAppend (Spans, NewSpan (S, 0, S->PC));
129     }
130
131     /* Walk over the spans, close open, remove empty ones */
132     for (I = 0, J = 0; I < CollCount (Spans); ++I) {
133
134         /* Get the next span */
135         Span* S = CollAtUnchecked (Spans, I);
136
137         /* Set the end offset */
138         if (S->Start == S->Seg->PC) {
139             /* Span is empty */
140             FreeSpan (S);
141         } else {
142             /* Span is not empty */
143             S->End = S->Seg->PC;
144             CollReplace (Spans, S, J++);
145         }
146     }
147
148     /* New Count is now in J */
149     Spans->Count = J;
150 }
151
152
153
154 void WriteSpans (const Collection* Spans)
155 /* Write a list of spans to the output file */
156 {
157     unsigned I;
158
159     /* Write the number of spans */
160     ObjWriteVar (CollCount (Spans));
161
162     /* Write the spans */
163     for (I = 0; I < CollCount (Spans); ++I) {
164
165         /* Get next range */
166         const Span* S = CollConstAt (Spans, I);
167
168         /* Write data for th span We will write the size instead of the end
169          * offset to save some bytes, since most spans are expected to be
170          * rather small.
171          */
172         ObjWriteVar (S->Seg->Num);
173         ObjWriteVar (S->Start);
174         ObjWriteVar (S->End - S->Start);
175     }
176 }
177
178
179
180