1 /*****************************************************************************/
5 /* Data output routines */
9 /* (C) 2000-2004 Ullrich von Bassewitz */
10 /* Römerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
46 /*****************************************************************************/
48 /*****************************************************************************/
52 static unsigned GetSpan (attr_t Style)
53 /* Get the number of bytes for a given style */
55 /* Get the number of bytes still available */
56 unsigned RemainingBytes = GetRemainingBytes ();
58 /* Count how many bytes are available. This number is limited by the
59 * number of remaining bytes, a label, or the end of the given Style
63 while (Count < RemainingBytes) {
64 if (MustDefLabel(PC+Count) || GetStyleAttr (PC+Count) != Style) {
70 /* Return the number of bytes */
76 static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (unsigned))
77 /* Output a table of bytes */
81 /* Count how many bytes may be output. */
82 unsigned Count = GetSpan (Style);
84 /* If the count is less than the member size, print a row of Count data
85 * bytes. We assume here that there is no member with a size that is less
88 if (Count < MemberSize) {
93 /* Make Count an even number of multiples of MemberSize */
94 Count &= ~(MemberSize-1);
96 /* Output as many data bytes lines as needed */
98 while (BytesLeft > 0) {
100 /* Calculate the number of bytes for the next line */
101 unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft;
103 /* Output a line with these bytes */
111 /* If the next line is not the same style, add a separator */
112 if (CodeLeft() && GetStyleAttr (PC) != Style) {
116 /* Return the number of bytes output */
122 unsigned ByteTable (void)
123 /* Output a table of bytes */
125 /* Call the low level function */
126 return DoTable (atByteTab, 1, DataByteLine);
131 unsigned DByteTable (void)
132 /* Output a table of dbytes */
134 /* Call the low level function */
135 return DoTable (atDByteTab, 2, DataDByteLine);
140 unsigned WordTable (void)
141 /* Output a table of words */
143 /* Call the low level function */
144 return DoTable (atWordTab, 2, DataWordLine);
149 unsigned DWordTable (void)
150 /* Output a table of double words */
152 /* Call the low level function */
153 return DoTable (atDWordTab, 4, DataDWordLine);
158 unsigned AddrTable (void)
159 /* Output a table of addresses */
163 /* Count how many bytes may be output. */
164 unsigned Count = GetSpan (atAddrTab);
166 /* Handle Count == 1 */
171 /* Make the given number even */
174 /* Output as many data bytes lines as needed. For addresses, each line
175 * will hold just one address.
178 while (BytesLeft > 0) {
180 /* Get the address */
181 unsigned Addr = GetCodeWord (PC);
183 /* In pass 1, define a label, in pass 2 output the line */
185 if (!HaveLabel (Addr)) {
186 AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
189 const char* Label = GetLabel (Addr);
191 /* OOPS! Should not happen */
192 Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
197 Output ("%s", Label);
207 /* If the next line is not a byte table line, add a separator */
208 if (CodeLeft() && GetStyleAttr (PC) != atAddrTab) {
212 /* Return the number of bytes output */
218 unsigned RtsTable (void)
219 /* Output a table of RTS addresses (address - 1) */
223 /* Count how many bytes may be output. */
224 unsigned Count = GetSpan (atRtsTab);
226 /* Handle Count == 1 */
231 /* Make the given number even */
234 /* Output as many data bytes lines as needed. For addresses, each line
235 * will hold just one address.
238 while (BytesLeft > 0) {
240 /* Get the address */
241 unsigned Addr = (GetCodeWord (PC) + 1) & 0xFFFF;
243 /* In pass 1, define a label, in pass 2 output the line */
245 if (!HaveLabel (Addr)) {
246 AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
249 const char* Label = GetLabel (Addr);
251 /* OOPS! Should not happen */
252 Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
257 Output ("%s-1", Label);
267 /* If the next line is not a byte table line, add a separator */
268 if (CodeLeft() && GetStyleAttr (PC) != atRtsTab) {
272 /* Return the number of bytes output */
278 unsigned TextTable (void)
279 /* Output a table of text messages */
281 /* Count how many bytes may be output. */
282 unsigned ByteCount = GetSpan (atTextTab);
284 /* Output as many data bytes lines as needed. */
285 unsigned BytesLeft = ByteCount;
286 while (BytesLeft > 0) {
290 /* Count the number of characters that can be output as such */
292 while (Count < BytesLeft && Count < BytesPerLine*4-1) {
293 unsigned char C = GetCodeByte (PC + Count);
294 if (C >= 0x20 && C <= 0x7E && C != '\"') {
301 /* If we have text, output it */
308 for (I = 0; I < Count; ++I) {
309 Output ("%c", GetCodeByte (PC+I));
314 unsigned Chunk = CBytes;
315 if (Chunk > BytesPerLine) {
316 Chunk = BytesPerLine;
318 LineComment (PC, Chunk);
326 /* Count the number of bytes that must be output as bytes */
328 while (Count < BytesLeft && Count < BytesPerLine) {
329 unsigned char C = GetCodeByte (PC + Count);
330 if (C < 0x20 || C > 0x7E || C == '\"') {
337 /* If we have raw output bytes, print them */
339 DataByteLine (Count);
346 /* If the next line is not a byte table line, add a separator */
347 if (CodeLeft() && GetStyleAttr (PC) != atTextTab) {
351 /* Return the number of bytes output */