/*****************************************************************************/
/* */
-/* listing.c */
+/* listing.c */
/* */
-/* Listing support for the ca65 crossassembler */
+/* Listing support for the ca65 crossassembler */
/* */
/* */
/* */
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
/* Single linked list of lines */
-ListLine* LineList = 0; /* List of listing lines */
-ListLine* LineCur = 0; /* Current listing line */
-ListLine* LineLast = 0; /* Last (current) listing line */
+ListLine* LineList = 0; /* List of listing lines */
+ListLine* LineCur = 0; /* Current listing line */
+ListLine* LineLast = 0; /* Last (current) listing line */
/* Page and other formatting */
-int PageLength = -1; /* Length of a listing page */
-static unsigned PageNumber = 1; /* Current listing page number */
-static int PageLines = 0; /* Current line on page */
-static unsigned ListBytes = 12; /* Number of bytes to list for one line */
+int PageLength = -1; /* Length of a listing page */
+static unsigned PageNumber = 1; /* Current listing page number */
+static int PageLines = 0; /* Current line on page */
+static unsigned ListBytes = 12; /* Number of bytes to list for one line */
/* Switch the listing on/off */
-static int ListingEnabled = 1; /* Enabled if > 0 */
+static int ListingEnabled = 1; /* Enabled if > 0 */
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
/* Store only if listing is enabled */
if (SB_GetLen (&ListingName) > 0) {
- ListLine* L;
-
- /* Get the length of the line */
- unsigned Len = SB_GetLen (Line);
-
- /* Ignore trailing newlines */
- while (Len > 0 && SB_AtUnchecked (Line, Len-1) == '\n') {
- --Len;
- }
-
- /* Allocate memory */
- L = xmalloc (sizeof (ListLine) + Len);
-
- /* Initialize the fields. */
- L->Next = 0;
- L->FragList = 0;
- L->FragLast = 0;
- L->PC = GetPC ();
- L->Reloc = GetRelocMode ();
- L->File = File;
- L->Depth = Depth;
- L->Output = (ListingEnabled > 0);
- L->ListBytes = (unsigned char) ListBytes;
- memcpy (L->Line, SB_GetConstBuf (Line), Len);
- L->Line[Len] = '\0';
-
- /* Insert the line into the list of lines */
- if (LineList == 0) {
- LineList = L;
- } else {
- LineLast->Next = L;
- }
- LineLast = L;
+ ListLine* L;
+
+ /* Get the length of the line */
+ unsigned Len = SB_GetLen (Line);
+
+ /* Ignore trailing newlines */
+ while (Len > 0 && SB_AtUnchecked (Line, Len-1) == '\n') {
+ --Len;
+ }
+
+ /* Allocate memory */
+ L = xmalloc (sizeof (ListLine) + Len);
+
+ /* Initialize the fields. */
+ L->Next = 0;
+ L->FragList = 0;
+ L->FragLast = 0;
+ L->PC = GetPC ();
+ L->Reloc = GetRelocMode ();
+ L->File = File;
+ L->Depth = Depth;
+ L->Output = (ListingEnabled > 0);
+ L->ListBytes = (unsigned char) ListBytes;
+ memcpy (L->Line, SB_GetConstBuf (Line), Len);
+ L->Line[Len] = '\0';
+
+ /* Insert the line into the list of lines */
+ if (LineList == 0) {
+ LineList = L;
+ } else {
+ LineLast->Next = L;
+ }
+ LineLast = L;
}
}
/* Enable output of lines to the listing */
{
if (SB_GetLen (&ListingName) > 0) {
- /* If we're about to enable the listing, do this for the current line
- * also, so we will see the source line that did this.
- */
- if (ListingEnabled++ == 0) {
- LineCur->Output = 1;
- }
+ /* If we're about to enable the listing, do this for the current line
+ * also, so we will see the source line that did this.
+ */
+ if (ListingEnabled++ == 0) {
+ LineCur->Output = 1;
+ }
}
}
/* Disable output of lines to the listing */
{
if (SB_GetLen (&ListingName) > 0) {
- if (ListingEnabled == 0) {
- /* Cannot switch the listing off once more */
- Error ("Counter underflow");
- } else {
- --ListingEnabled;
- }
+ if (ListingEnabled == 0) {
+ /* Cannot switch the listing off once more */
+ Error ("Counter underflow");
+ } else {
+ --ListingEnabled;
+ }
}
}
/* Set the maximum number of bytes listed for one line */
{
if (Bytes < 0) {
- Bytes = 0; /* Encode "unlimited" as zero */
+ Bytes = 0; /* Encode "unlimited" as zero */
}
ListBytes = Bytes;
}
/* Initialize the current listing line */
{
if (SB_GetLen (&ListingName) > 0) {
- /* Make the last loaded line the current line */
- /* ###### This code is a hack! We really need to do it right
- * as soon as we know, how:-(
- */
- if (LineCur && LineCur->Next && LineCur->Next != LineLast) {
- ListLine* L = LineCur;
- do {
- L = L->Next;
- /* Set the values for this line */
- CHECK (L != 0);
- L->PC = GetPC ();
- L->Reloc = GetRelocMode ();
- L->Output = (ListingEnabled > 0);
- L->ListBytes = (unsigned char) ListBytes;
- } while (L->Next != LineLast);
- }
- LineCur = LineLast;
-
- /* Set the values for this line */
- CHECK (LineCur != 0);
- LineCur->PC = GetPC ();
- LineCur->Reloc = GetRelocMode ();
- LineCur->Output = (ListingEnabled > 0);
- LineCur->ListBytes = (unsigned char) ListBytes;
+ /* Make the last loaded line the current line */
+ /* ###### This code is a hack! We really need to do it right
+ * as soon as we know, how:-(
+ */
+ if (LineCur && LineCur->Next && LineCur->Next != LineLast) {
+ ListLine* L = LineCur;
+ do {
+ L = L->Next;
+ /* Set the values for this line */
+ CHECK (L != 0);
+ L->PC = GetPC ();
+ L->Reloc = GetRelocMode ();
+ L->Output = (ListingEnabled > 0);
+ L->ListBytes = (unsigned char) ListBytes;
+ } while (L->Next != LineLast);
+ }
+ LineCur = LineLast;
+
+ /* Set the values for this line */
+ CHECK (LineCur != 0);
+ LineCur->PC = GetPC ();
+ LineCur->Reloc = GetRelocMode ();
+ LineCur->Output = (ListingEnabled > 0);
+ LineCur->ListBytes = (unsigned char) ListBytes;
}
}
/* Add a hex byte in ASCII to the given string and return the new pointer */
{
static const char HexTab [16] = {
- '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
*S++ = HexTab [(Val >> 4) & 0x0F];
/* Print the header on the new page */
fprintf (F,
- "ca65 V%s\n"
- "Main file : %s\n"
- "Current file: %.*s\n"
- "\n",
- GetVersionAsString (),
- InFile,
- (int) SB_GetLen (CurFile), SB_GetConstBuf (CurFile));
+ "ca65 V%s\n"
+ "Main file : %s\n"
+ "Current file: %.*s\n"
+ "\n",
+ GetVersionAsString (),
+ InFile,
+ (int) SB_GetLen (CurFile), SB_GetConstBuf (CurFile));
/* Count pages, reset lines */
++PageNumber;
* the last one, to avoid pages that consist of just the header.
*/
if (PageLength > 0 && PageLines >= PageLength && L->Next != 0) {
- /* Do a formfeed */
- putc ('\f', F);
- /* Print the header on the new page */
- PrintPageHeader (F, L);
+ /* Do a formfeed */
+ putc ('\f', F);
+ /* Print the header on the new page */
+ PrintPageHeader (F, L);
}
}
/* Open the real listing file */
F = fopen (SB_GetConstBuf (&ListingName), "w");
if (F == 0) {
- Fatal ("Cannot open listing file `%s': %s",
+ Fatal ("Cannot open listing file `%s': %s",
SB_GetConstBuf (&ListingName),
strerror (errno));
}
L = LineList;
while (L) {
- char* Buf;
- char* B;
- unsigned Count;
- unsigned I;
- char* Line;
-
- /* If we should not output this line, go to the next */
- if (L->Output == 0) {
- L = L->Next;
- continue;
- }
-
- /* If we don't have a fragment list for this line, things are easy */
- if (L->FragList == 0) {
- PrintLine (F, MakeLineHeader (HeaderBuf, L), L->Line, L);
- L = L->Next;
- continue;
- }
-
- /* Count the number of bytes in the complete fragment list */
- Count = 0;
- Frag = L->FragList;
- while (Frag) {
- Count += Frag->Len;
- Frag = Frag->LineList;
- }
-
- /* Allocate memory for the given number of bytes */
- Buf = xmalloc (Count*2+1);
-
- /* Copy an ASCII representation of the bytes into the buffer */
- B = Buf;
- Frag = L->FragList;
- while (Frag) {
-
- /* Write data depending on the type */
- switch (Frag->Type) {
-
- case FRAG_LITERAL:
- for (I = 0; I < Frag->Len; ++I) {
- B = AddHex (B, Frag->V.Data[I]);
- }
- break;
-
- case FRAG_EXPR:
- case FRAG_SEXPR:
- B = AddMult (B, 'r', Frag->Len*2);
- break;
-
- case FRAG_FILL:
- B = AddMult (B, 'x', Frag->Len*2);
- break;
-
- default:
- Internal ("Invalid fragment type: %u", Frag->Type);
-
- }
-
- /* Next fragment */
- Frag = Frag->LineList;
-
- }
-
- /* Limit the number of bytes actually printed */
- if (L->ListBytes != 0) {
- /* Not unlimited */
- if (Count > L->ListBytes) {
- Count = L->ListBytes;
- }
- }
-
- /* Output the data. The format of a listing line is:
- *
- * PPPPPPm I 11 22 33 44
- *
- * where
- *
- * PPPPPP is the PC
- * m is the mode ('r' or empty)
- * I is the include level
- * 11 .. are code or data bytes
- */
- Line = L->Line;
- B = Buf;
- while (Count) {
-
- unsigned Chunk;
- char* P;
-
- /* Prepare the line header */
- MakeLineHeader (HeaderBuf, L);
-
- /* Get the number of bytes for the next line */
- Chunk = Count;
- if (Chunk > 4) {
- Chunk = 4;
- }
- Count -= Chunk;
-
- /* Increment the program counter. Since we don't need the PC stored
- * in the LineList object for anything else, just increment this
- * variable.
- */
- L->PC += Chunk;
-
- /* Copy the bytes into the line */
- P = HeaderBuf + 11;
- for (I = 0; I < Chunk; ++I) {
- *P++ = *B++;
- *P++ = *B++;
- *P++ = ' ';
- }
-
- /* Output this line */
- PrintLine (F, HeaderBuf, Line, L);
-
- /* Don't output a line twice */
- Line = "";
-
- }
-
- /* Delete the temporary buffer */
- xfree (Buf);
-
- /* Next line */
- L = L->Next;
+ char* Buf;
+ char* B;
+ unsigned Count;
+ unsigned I;
+ char* Line;
+
+ /* If we should not output this line, go to the next */
+ if (L->Output == 0) {
+ L = L->Next;
+ continue;
+ }
+
+ /* If we don't have a fragment list for this line, things are easy */
+ if (L->FragList == 0) {
+ PrintLine (F, MakeLineHeader (HeaderBuf, L), L->Line, L);
+ L = L->Next;
+ continue;
+ }
+
+ /* Count the number of bytes in the complete fragment list */
+ Count = 0;
+ Frag = L->FragList;
+ while (Frag) {
+ Count += Frag->Len;
+ Frag = Frag->LineList;
+ }
+
+ /* Allocate memory for the given number of bytes */
+ Buf = xmalloc (Count*2+1);
+
+ /* Copy an ASCII representation of the bytes into the buffer */
+ B = Buf;
+ Frag = L->FragList;
+ while (Frag) {
+
+ /* Write data depending on the type */
+ switch (Frag->Type) {
+
+ case FRAG_LITERAL:
+ for (I = 0; I < Frag->Len; ++I) {
+ B = AddHex (B, Frag->V.Data[I]);
+ }
+ break;
+
+ case FRAG_EXPR:
+ case FRAG_SEXPR:
+ B = AddMult (B, 'r', Frag->Len*2);
+ break;
+
+ case FRAG_FILL:
+ B = AddMult (B, 'x', Frag->Len*2);
+ break;
+
+ default:
+ Internal ("Invalid fragment type: %u", Frag->Type);
+
+ }
+
+ /* Next fragment */
+ Frag = Frag->LineList;
+
+ }
+
+ /* Limit the number of bytes actually printed */
+ if (L->ListBytes != 0) {
+ /* Not unlimited */
+ if (Count > L->ListBytes) {
+ Count = L->ListBytes;
+ }
+ }
+
+ /* Output the data. The format of a listing line is:
+ *
+ * PPPPPPm I 11 22 33 44
+ *
+ * where
+ *
+ * PPPPPP is the PC
+ * m is the mode ('r' or empty)
+ * I is the include level
+ * 11 .. are code or data bytes
+ */
+ Line = L->Line;
+ B = Buf;
+ while (Count) {
+
+ unsigned Chunk;
+ char* P;
+
+ /* Prepare the line header */
+ MakeLineHeader (HeaderBuf, L);
+
+ /* Get the number of bytes for the next line */
+ Chunk = Count;
+ if (Chunk > 4) {
+ Chunk = 4;
+ }
+ Count -= Chunk;
+
+ /* Increment the program counter. Since we don't need the PC stored
+ * in the LineList object for anything else, just increment this
+ * variable.
+ */
+ L->PC += Chunk;
+
+ /* Copy the bytes into the line */
+ P = HeaderBuf + 11;
+ for (I = 0; I < Chunk; ++I) {
+ *P++ = *B++;
+ *P++ = *B++;
+ *P++ = ' ';
+ }
+
+ /* Output this line */
+ PrintLine (F, HeaderBuf, Line, L);
+
+ /* Don't output a line twice */
+ Line = "";
+
+ }
+
+ /* Delete the temporary buffer */
+ xfree (Buf);
+
+ /* Next line */
+ L = L->Next;
}