diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 1e296d9c2..c34b14398 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -102,6 +102,7 @@ Short options: -mm model Set the memory model -o name Name the output file -s Enable smart mode + -S Generate segment offsets in listing -t sys Set the target system -v Increase verbosity @@ -127,6 +128,7 @@ Long options: --no-utf8 Disable use of UTF-8 in diagnostics --pagelength n Set the page length for the listing --relax-checks Relax some checks (see docs) + --segment-list Generate segment offsets in listing --smart Enable smart mode --target sys Set the target system --verbose Increase verbosity diff --git a/src/ca65/global.c b/src/ca65/global.c index e8599a675..1398ce2c7 100644 --- a/src/ca65/global.c +++ b/src/ca65/global.c @@ -69,6 +69,7 @@ unsigned char RelaxChecks = 0; /* Relax a few assembler checks */ unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */ unsigned char LongJsrJmpRts = 0; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */ unsigned char WarningsAsErrors = 0; /* Error if any warnings */ +unsigned char SegList = 0; /* Show segments in listing */ unsigned char ExpandMacros = 0; /* Expand macros in listing */ /* Emulation features */ diff --git a/src/ca65/global.h b/src/ca65/global.h index 5ec4a8d82..1923bc748 100644 --- a/src/ca65/global.h +++ b/src/ca65/global.h @@ -71,6 +71,7 @@ extern unsigned char RelaxChecks; /* Relax a few assembler checks */ extern unsigned char StringEscapes; /* Allow C-style escapes in strings */ extern unsigned char LongJsrJmpRts; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */ extern unsigned char WarningsAsErrors; /* Error if any warnings */ +extern unsigned char SegList; /* Show segments in listing */ extern unsigned char ExpandMacros; /* Expand macros in listing */ /* Emulation features */ diff --git a/src/ca65/listing.c b/src/ca65/listing.c index b3f3d9282..2c6b32f87 100644 --- a/src/ca65/listing.c +++ b/src/ca65/listing.c @@ -75,7 +75,6 @@ static unsigned ListBytes = 12; /* Number of bytes to list for one line static int ListingEnabled = 1; /* Enabled if > 0 */ - /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -105,6 +104,7 @@ void NewListingLine (const StrBuf* Line, unsigned char File, unsigned char Depth L->Next = 0; L->FragList = 0; L->FragLast = 0; + L->Seg = ActiveSeg->Num; L->PC = GetPC (); L->Reloc = GetRelocMode (); L->File = File; @@ -181,6 +181,7 @@ void InitListingLine (void) L = L->Next; /* Set the values for this line */ CHECK (L != 0); + L->Seg = ActiveSeg->Num; L->PC = GetPC (); L->Reloc = GetRelocMode (); L->Output = (ListingEnabled > 0); @@ -191,6 +192,7 @@ void InitListingLine (void) /* Set the values for this line */ CHECK (LineCur != 0); + LineCur->Seg = ActiveSeg->Num; LineCur->PC = GetPC (); LineCur->Reloc = GetRelocMode (); LineCur->Output = (ListingEnabled > 0); @@ -276,7 +278,7 @@ static char* MakeLineHeader (char* H, const ListLine* L) { char Mode; char Depth; - + unsigned Offset = 0; /* Setup the PC mode */ Mode = (L->Reloc)? 'r' : ' '; @@ -284,8 +286,17 @@ static char* MakeLineHeader (char* H, const ListLine* L) Depth = (L->Depth < 10)? L->Depth + '0' : '+'; /* Format the line */ - sprintf (H, "%06lX%c %c", L->PC, Mode, Depth); - memset (H+9, ' ', LINE_HEADER_LEN-9); + if (!SegList) { + Offset = 9; + sprintf (H, "%06lX%c %c", L->PC, Mode, Depth); + } else if (L->Reloc) { + Offset = 12; + sprintf (H, "%02X.%06lX%c %c",L->Seg, L->PC, Mode, Depth); + } else { + Offset = 12; + sprintf (H, " %06lX%c %c", L->PC, Mode, Depth); + } + memset (H + Offset, ' ', LINE_HEADER_LEN - Offset - (SegList?0:3)); /* Return the buffer */ return H; @@ -313,8 +324,11 @@ void CreateListing (void) PageNumber = 0; PrintPageHeader (F, LineList); - /* Terminate the header buffer. The last byte will never get overwritten */ - HeaderBuf [LINE_HEADER_LEN] = '\0'; + /* Terminate the header buffer. The last byte will never get overwritten + ** the - 3 adjust is for when the segnum gets prepended to the header. + */ + + HeaderBuf [(SegList ? LINE_HEADER_LEN : LINE_HEADER_LEN - 3)] = '\0'; /* Walk through all listing lines */ L = LineList; @@ -426,7 +440,7 @@ void CreateListing (void) L->PC += Chunk; /* Copy the bytes into the line */ - P = HeaderBuf + 11; + P = HeaderBuf + (SegList?14: 11); for (I = 0; I < Chunk; ++I) { *P++ = *B++; *P++ = *B++; @@ -448,7 +462,9 @@ void CreateListing (void) L = L->Next; } - + if (SegList) { + ListSegments (F); + } /* Close the listing file */ (void) fclose (F); } diff --git a/src/ca65/listing.h b/src/ca65/listing.h index b1ae44291..425cb47b5 100644 --- a/src/ca65/listing.h +++ b/src/ca65/listing.h @@ -60,7 +60,7 @@ struct StrBuf; /* Length of the header of a listing line */ -#define LINE_HEADER_LEN 24 +#define LINE_HEADER_LEN 27 /* One listing line as it is stored in memory */ typedef struct ListLine ListLine; @@ -68,6 +68,7 @@ struct ListLine { ListLine* Next; /* Pointer to next line */ Fragment* FragList; /* List of fragments for this line */ Fragment* FragLast; /* Last entry in fragment list */ + unsigned Seg; /* Which segment this line targets */ unsigned long PC; /* Program counter for this line */ unsigned char Reloc; /* Relocatable mode? */ unsigned char File; /* From which file is the line? */ diff --git a/src/ca65/main.c b/src/ca65/main.c index 40a9bacaa..66a0f38af 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -107,6 +107,7 @@ static void Usage (void) " -mm model\t\t\tSet the memory model\n" " -o name\t\t\tName the output file\n" " -s\t\t\t\tEnable smart mode\n" + " -S\t\t\t\tEnable segment offset listing\n" " -t sys\t\t\tSet the target system\n" " -v\t\t\t\tIncrease verbosity\n" " -x\t\t\t\tExpand macros\n" @@ -132,6 +133,7 @@ static void Usage (void) " --no-utf8\t\t\tDisable use of UTF-8 in diagnostics\n" " --pagelength n\t\tSet the page length for the listing\n" " --relax-checks\t\tRelax some checks (see docs)\n" + " --segment-list\t\tEnable segment offset listing\n" " --smart\t\t\tEnable smart mode\n" " --target sys\t\t\tSet the target system\n" " --verbose\t\t\tIncrease verbosity\n" @@ -743,7 +745,12 @@ static void OptVersion (const char* Opt attribute ((unused)), exit (EXIT_SUCCESS); } - +static void OptSeglist (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) + /* Enable segment listing */ +{ + SegList = 1; +} static void OptWarningsAsErrors (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) @@ -1074,6 +1081,7 @@ int main (int argc, char* argv []) { "--no-utf8", 0, OptNoUtf8 }, { "--pagelength", 1, OptPageLength }, { "--relax-checks", 0, OptRelaxChecks }, + { "--segment-list", 0, OptSeglist }, { "--smart", 0, OptSmart }, { "--target", 1, OptTarget }, { "--verbose", 0, OptVerbose }, @@ -1162,6 +1170,10 @@ int main (int argc, char* argv []) OptSmart (Arg, 0); break; + case 'S': + OptSeglist (Arg, 0); + break; + case 't': OptTarget (Arg, GetArg (&I, 2)); break; diff --git a/src/ca65/segment.c b/src/ca65/segment.c index bd0838951..adc5cec98 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -476,7 +476,18 @@ void SegDump (void) printf ("\n"); } - +void ListSegments (FILE* destination) +{ + /* summary of segments when seglist requested */ + unsigned I; + fprintf (destination, "\nSegment summary\n\n"); + for (I = 0; I < CollCount (&SegmentList); ++I) { + Segment* S = CollAtUnchecked (&SegmentList, I); + if(S->FragCount) { + fprintf (destination, "Segment: %02X = %s\n", S->Num, S->Def->Name); + } + } +} void SegInit (void) /* Initialize segments */ diff --git a/src/ca65/segment.h b/src/ca65/segment.h index 8e3dd2fdd..35430739b 100644 --- a/src/ca65/segment.h +++ b/src/ca65/segment.h @@ -36,7 +36,7 @@ #ifndef SEGMENT_H #define SEGMENT_H - +#include /* common */ #include "coll.h" @@ -95,6 +95,9 @@ extern Segment* ActiveSeg; Fragment* GenFragment (unsigned char Type, unsigned short Len); /* Generate a new fragment, add it to the current segment and return it. */ +void ListSegments (FILE* destination); +/* List the segments to the given file when seglist set */ + void UseSeg (const SegDef* D); /* Use the given segment */