/*****************************************************************************/
/* */
-/* data.c */
+/* data.c */
/* */
-/* Data output routines */
+/* Data output routines */
/* */
/* */
/* */
-/* (C) 2000-2004 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2000-2014, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include "code.h"
#include "error.h"
#include "global.h"
+#include "labels.h"
#include "output.h"
#include "data.h"
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
unsigned RemainingBytes = GetRemainingBytes ();
/* Count how many bytes are available. This number is limited by the
- * number of remaining bytes, a label, or the end of the given Style
- * attribute.
- */
+ ** number of remaining bytes, a label, a segment change, or the end of
+ ** the given Style attribute.
+ */
unsigned Count = 1;
while (Count < RemainingBytes) {
- if (MustDefLabel(PC+Count) || GetStyleAttr (PC+Count) != Style) {
- break;
- }
- ++Count;
+ attr_t Attr;
+ if (MustDefLabel(PC+Count)) {
+ break;
+ }
+ Attr = GetAttr (PC+Count);
+ if ((Attr & atStyleMask) != Style) {
+ break;
+ }
+ if ((Attr & (atSegmentStart | atSegmentEnd))) {
+ break;
+ }
+ ++Count;
}
/* Return the number of bytes */
unsigned Count = GetSpan (Style);
/* If the count is less than the member size, print a row of Count data
- * bytes. We assume here that there is no member with a size that is less
- * than BytesPerLine.
- */
+ ** bytes. We assume here that there is no member with a size that is less
+ ** than BytesPerLine.
+ */
if (Count < MemberSize) {
- DataByteLine (Count);
- return Count;
+ DataByteLine (Count);
+ PC += Count;
+ return Count;
}
/* Make Count an even number of multiples of MemberSize */
BytesLeft = Count;
while (BytesLeft > 0) {
- /* Calculate the number of bytes for the next line */
- unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft;
+ /* Calculate the number of bytes for the next line */
+ unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft;
- /* Output a line with these bytes */
- TableFunc (Chunk);
+ /* Output a line with these bytes */
+ TableFunc (Chunk);
- /* Next line */
- BytesLeft -= Chunk;
- PC += Chunk;
+ /* Next line */
+ BytesLeft -= Chunk;
+ PC += Chunk;
}
/* If the next line is not the same style, add a separator */
if (CodeLeft() && GetStyleAttr (PC) != Style) {
- SeparatorLine ();
+ SeparatorLine ();
}
/* Return the number of bytes output */
unsigned AddrTable (void)
/* Output a table of addresses */
{
- unsigned BytesLeft;
-
- /* Count how many bytes may be output. */
- unsigned Count = GetSpan (atAddrTab);
-
- /* Handle Count == 1 */
- if (Count == 1) {
- ByteTable ();
- }
-
- /* Make the given number even */
- Count &= ~1U;
-
- /* Output as many data bytes lines as needed. For addresses, each line
- * will hold just one address.
- */
- BytesLeft = Count;
- while (BytesLeft > 0) {
-
- /* Get the address */
- unsigned Addr = GetCodeWord (PC);
-
- /* In pass 1, define a label, in pass 2 output the line */
- if (Pass == 1) {
- if (!HaveLabel (Addr)) {
- AddIntLabel (Addr);
- }
- } else {
- const char* Label = GetLabel (Addr);
- if (Label == 0) {
- /* OOPS! Should not happen */
- Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
- }
- Indent (MIndent);
- Output (".addr");
- Indent (AIndent);
- Output ("%s", Label);
- LineComment (PC, 2);
- LineFeed ();
- }
-
- /* Next line */
- PC += 2;
- BytesLeft -= 2;
+ unsigned long BytesLeft = GetRemainingBytes ();
+ unsigned long Start = PC;
+
+ /* Loop while table bytes left and we don't need to create a label at the
+ ** current position.
+ */
+ while (BytesLeft && GetStyleAttr (PC) == atAddrTab) {
+
+ unsigned Addr;
+
+ /* If just one byte is left, define it and bail out */
+ if (BytesLeft == 1 || GetStyleAttr (PC+1) != atAddrTab) {
+ DataByteLine (1);
+ ++PC;
+ break;
+ }
+
+ /* More than one byte left. Define a forward label if necessary */
+ ForwardLabel (1);
+
+ /* Now get the address from the PC */
+ Addr = GetCodeWord (PC);
+
+ /* In pass 1, define a label, in pass 2 output the line */
+ if (Pass == 1) {
+ if (!HaveLabel (Addr)) {
+ AddIntLabel (Addr);
+ }
+ } else {
+ const char* Label = GetLabel (Addr, PC);
+ if (Label == 0) {
+ /* OOPS! Should not happen */
+ Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
+ }
+ Indent (MCol);
+ Output (".addr");
+ Indent (ACol);
+ Output ("%s", Label);
+ LineComment (PC, 2);
+ LineFeed ();
+ }
+
+ /* Next table entry */
+ PC += 2;
+ BytesLeft -= 2;
+
+ /* If we must define a label here, bail out */
+ if (BytesLeft && MustDefLabel (PC)) {
+ break;
+ }
}
- /* If the next line is not a byte table line, add a separator */
+ /* If the next line is not an address table line, add a separator */
if (CodeLeft() && GetStyleAttr (PC) != atAddrTab) {
- SeparatorLine ();
+ SeparatorLine ();
}
/* Return the number of bytes output */
- return Count;
+ return PC - Start;
}
unsigned RtsTable (void)
/* Output a table of RTS addresses (address - 1) */
{
- unsigned BytesLeft;
-
- /* Count how many bytes may be output. */
- unsigned Count = GetSpan (atRtsTab);
-
- /* Handle Count == 1 */
- if (Count == 1) {
- ByteTable ();
+ unsigned long BytesLeft = GetRemainingBytes ();
+ unsigned long Start = PC;
+
+ /* Loop while table bytes left and we don't need to create a label at the
+ ** current position.
+ */
+ while (BytesLeft && GetStyleAttr (PC) == atRtsTab) {
+
+ unsigned Addr;
+
+ /* If just one byte is left, define it and bail out */
+ if (BytesLeft == 1 || GetStyleAttr (PC+1) != atRtsTab) {
+ DataByteLine (1);
+ ++PC;
+ break;
+ }
+
+ /* More than one byte left. Define a forward label if necessary */
+ ForwardLabel (1);
+
+ /* Now get the address from the PC */
+ Addr = (GetCodeWord (PC) + 1) & 0xFFFF;
+
+ /* In pass 1, define a label, in pass 2 output the line */
+ if (Pass == 1) {
+ if (!HaveLabel (Addr)) {
+ AddIntLabel (Addr);
+ }
+ } else {
+ const char* Label = GetLabel (Addr, PC);
+ if (Label == 0) {
+ /* OOPS! Should not happen */
+ Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
+ }
+ Indent (MCol);
+ Output (".word");
+ Indent (ACol);
+ Output ("%s-1", Label);
+ LineComment (PC, 2);
+ LineFeed ();
+ }
+
+ /* Next table entry */
+ PC += 2;
+ BytesLeft -= 2;
+
+ /* If we must define a label here, bail out */
+ if (BytesLeft && MustDefLabel (PC)) {
+ break;
+ }
}
- /* Make the given number even */
- Count &= ~1U;
-
- /* Output as many data bytes lines as needed. For addresses, each line
- * will hold just one address.
- */
- BytesLeft = Count;
- while (BytesLeft > 0) {
-
- /* Get the address */
- unsigned Addr = (GetCodeWord (PC) + 1) & 0xFFFF;
-
- /* In pass 1, define a label, in pass 2 output the line */
- if (Pass == 1) {
- if (!HaveLabel (Addr)) {
- AddIntLabel (Addr);
- }
- } else {
- const char* Label = GetLabel (Addr);
- if (Label == 0) {
- /* OOPS! Should not happen */
- Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
- }
- Indent (MIndent);
- Output (".word");
- Indent (AIndent);
- Output ("%s-1", Label);
- LineComment (PC, 2);
- LineFeed ();
- }
-
- /* Next line */
- PC += 2;
- BytesLeft -= 2;
- }
-
- /* If the next line is not a byte table line, add a separator */
+ /* If the next line is not a return address table line, add a separator */
if (CodeLeft() && GetStyleAttr (PC) != atRtsTab) {
- SeparatorLine ();
+ SeparatorLine ();
}
/* Return the number of bytes output */
- return Count;
+ return PC - Start;
}
unsigned BytesLeft = ByteCount;
while (BytesLeft > 0) {
- unsigned I;
-
- /* Count the number of characters that can be output as such */
- unsigned Count = 0;
- while (Count < BytesLeft && Count < BytesPerLine*4-1) {
- unsigned char C = GetCodeByte (PC + Count);
- if (C >= 0x20 && C <= 0x7E && C != '\"') {
- ++Count;
- } else {
- break;
- }
- }
-
- /* If we have text, output it */
- if (Count > 0) {
- unsigned CBytes;
- Indent (MIndent);
- Output (".byte");
- Indent (AIndent);
- Output ("\"");
- for (I = 0; I < Count; ++I) {
- Output ("%c", GetCodeByte (PC+I));
- }
- Output ("\"");
- CBytes = Count;
- while (CBytes > 0) {
- unsigned Chunk = CBytes;
- if (Chunk > BytesPerLine) {
- Chunk = BytesPerLine;
- }
- LineComment (PC, Chunk);
- LineFeed ();
- CBytes -= Chunk;
- PC += Chunk;
- }
- BytesLeft -= Count;
- }
-
- /* Count the number of bytes that must be output as bytes */
- Count = 0;
- while (Count < BytesLeft && Count < BytesPerLine) {
- unsigned char C = GetCodeByte (PC + Count);
- if (C < 0x20 || C > 0x7E || C == '\"') {
- ++Count;
- } else {
- break;
- }
- }
-
- /* If we have raw output bytes, print them */
- if (Count > 0) {
- DataByteLine (Count);
- PC += Count;
- BytesLeft -= Count;
- }
+ unsigned I;
+
+ /* Count the number of characters that can be output as such */
+ unsigned Count = 0;
+ while (Count < BytesLeft && Count < BytesPerLine*4-1) {
+ unsigned char C = GetCodeByte (PC + Count);
+ if (C >= 0x20 && C <= 0x7E && C != '\"') {
+ ++Count;
+ } else {
+ break;
+ }
+ }
+
+ /* If we have text, output it */
+ if (Count > 0) {
+ unsigned CBytes;
+ Indent (MCol);
+ Output (".byte");
+ Indent (ACol);
+ Output ("\"");
+ for (I = 0; I < Count; ++I) {
+ Output ("%c", GetCodeByte (PC+I));
+ }
+ Output ("\"");
+ CBytes = Count;
+ while (CBytes > 0) {
+ unsigned Chunk = CBytes;
+ if (Chunk > BytesPerLine) {
+ Chunk = BytesPerLine;
+ }
+ LineComment (PC, Chunk);
+ LineFeed ();
+ CBytes -= Chunk;
+ PC += Chunk;
+ }
+ BytesLeft -= Count;
+ }
+
+ /* Count the number of bytes that must be output as bytes */
+ Count = 0;
+ while (Count < BytesLeft && Count < BytesPerLine) {
+ unsigned char C = GetCodeByte (PC + Count);
+ if (C < 0x20 || C > 0x7E || C == '\"') {
+ ++Count;
+ } else {
+ break;
+ }
+ }
+
+ /* If we have raw output bytes, print them */
+ if (Count > 0) {
+ DataByteLine (Count);
+ PC += Count;
+ BytesLeft -= Count;
+ }
}
/* If the next line is not a byte table line, add a separator */
if (CodeLeft() && GetStyleAttr (PC) != atTextTab) {
- SeparatorLine ();
+ SeparatorLine ();
}
/* Return the number of bytes output */
return ByteCount;
}
-
-
-