From cfca3473b8fc73299f55dfb1eb62d7e8eafaa5ed Mon Sep 17 00:00:00 2001 From: cuz Date: Mon, 30 Jan 2006 21:03:14 +0000 Subject: [PATCH] Added new options and info file attribute to set the columns where the fields of the disassembled output start. git-svn-id: svn://svn.cc65.org/cc65/trunk@3703 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/da65/data.c | 12 ++-- src/da65/global.c | 8 +-- src/da65/global.h | 36 ++++++++++-- src/da65/handler.c | 4 +- src/da65/infofile.c | 58 ++++++++++++++++++- src/da65/main.c | 133 +++++++++++++++++++++++++++++++++++++++----- src/da65/output.c | 34 +++++------ src/da65/scanner.h | 8 ++- 8 files changed, 240 insertions(+), 53 deletions(-) diff --git a/src/da65/data.c b/src/da65/data.c index 9a7ffc5b4..9f4514b87 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -192,9 +192,9 @@ unsigned AddrTable (void) /* OOPS! Should not happen */ Internal ("OOPS - Label for address 0x%06X disappeard!", Addr); } - Indent (MIndent); + Indent (MCol); Output (".addr"); - Indent (AIndent); + Indent (ACol); Output ("%s", Label); LineComment (PC, 2); LineFeed (); @@ -257,9 +257,9 @@ unsigned RtsTable (void) /* OOPS! Should not happen */ Internal ("OOPS - Label for address 0x%06X disappeard!", Addr); } - Indent (MIndent); + Indent (MCol); Output (".word"); - Indent (AIndent); + Indent (ACol); Output ("%s-1", Label); LineComment (PC, 2); LineFeed (); @@ -312,9 +312,9 @@ unsigned TextTable (void) /* If we have text, output it */ if (Count > 0) { unsigned CBytes; - Indent (MIndent); + Indent (MCol); Output (".byte"); - Indent (AIndent); + Indent (ACol); Output ("\""); for (I = 0; I < Count; ++I) { Output ("%c", GetCodeByte (PC+I)); diff --git a/src/da65/global.c b/src/da65/global.c index 40c8949c5..8f2a27aee 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -70,10 +70,10 @@ unsigned Comments = 0; /* Add which comments to the output? */ /* Page formatting */ unsigned PageLength = 0; /* Length of a listing page */ unsigned LBreak = 7; /* Linefeed if labels exceed this limit */ -unsigned MIndent = 9; /* Mnemonic indent */ -unsigned AIndent = 17; /* Argument indent */ -unsigned CIndent = 49; /* Comment indent */ -unsigned TIndent = 81; /* Text bytes indent */ +unsigned MCol = 9; /* Mnemonic column */ +unsigned ACol = 17; /* Argument column */ +unsigned CCol = 49; /* Comment column */ +unsigned TCol = 81; /* Text bytes column */ unsigned BytesPerLine = 8; /* Max. number of data bytes per line */ diff --git a/src/da65/global.h b/src/da65/global.h index bd0b07a4f..d8aafbdc1 100644 --- a/src/da65/global.h +++ b/src/da65/global.h @@ -74,12 +74,36 @@ extern unsigned Comments; /* Add which comments to the output? */ #define MIN_PAGE_LEN 32 #define MAX_PAGE_LEN 127 extern unsigned PageLength; /* Length of a listing page */ -extern unsigned LBreak; /* Linefeed if labels exceed this limit */ -extern unsigned MIndent; /* Mnemonic indent */ -extern unsigned AIndent; /* Argument indent */ -extern unsigned CIndent; /* Comment indent */ -extern unsigned TIndent; /* Text bytes indent */ -extern unsigned BytesPerLine; /* Max. number of data bytes per line */ + +/* Linefeed if labels exceed this limit */ +#define MIN_LABELBREAK 1 +#define MAX_LABELBREAK 128 +extern unsigned LBreak; + +/* Mnemonic column */ +#define MIN_MCOL 1 +#define MAX_MCOL 127 +extern unsigned MCol; + +/* Argument column */ +#define MIN_ACOL 1 +#define MAX_ACOL 127 +extern unsigned ACol; + +/* Comment column */ +#define MIN_CCOL 1 +#define MAX_CCOL 127 +extern unsigned CCol; + +/* Text bytes column */ +#define MIN_TCOL 1 +#define MAX_TCOL 127 +extern unsigned TCol; + +/* Max. number of data bytes per line */ +#define MIN_BYTESPERLINE 1 +#define MAX_BYTESPERLINE 127 +extern unsigned BytesPerLine; diff --git a/src/da65/handler.c b/src/da65/handler.c index 7ae97f7f7..f7412ff77 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -59,7 +59,7 @@ static void Mnemonic (const char* M) /* Indent and output a mnemonic */ { - Indent (MIndent); + Indent (MCol); Output ("%s", M); } @@ -79,7 +79,7 @@ static void OneLine (const OpcDesc* D, const char* Arg, ...) va_start (ap, Arg); xvsprintf (Buf, sizeof (Buf), Arg, ap); va_end (ap); - Indent (AIndent); + Indent (ACol); Output (Buf); /* Add the code stuff as comment */ diff --git a/src/da65/infofile.c b/src/da65/infofile.c index b52d9c5d3..3491f15bd 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -83,16 +83,24 @@ static void GlobalSection (void) /* Parse a global section */ { static const IdentTok GlobalDefs[] = { + { "ARGUMENTCOL", INFOTOK_ARGUMENT_COLUMN }, + { "ARGUMENTCOLUMN", INFOTOK_ARGUMENT_COLUMN }, + { "COMMENTCOL", INFOTOK_COMMENT_COLUMN }, + { "COMMENTCOLUMN", INFOTOK_COMMENT_COLUMN }, { "COMMENTS", INFOTOK_COMMENTS }, { "CPU", INFOTOK_CPU }, { "HEXOFFS", INFOTOK_HEXOFFS }, - { "INPUTNAME", INFOTOK_INPUTNAME }, + { "INPUTNAME", INFOTOK_INPUTNAME }, { "INPUTOFFS", INFOTOK_INPUTOFFS }, { "INPUTSIZE", INFOTOK_INPUTSIZE }, { "LABELBREAK", INFOTOK_LABELBREAK }, + { "MNEMONICCOL", INFOTOK_MNEMONIC_COLUMN }, + { "MNEMONICCOLUMN", INFOTOK_MNEMONIC_COLUMN }, { "OUTPUTNAME", INFOTOK_OUTPUTNAME }, { "PAGELENGTH", INFOTOK_PAGELENGTH }, - { "STARTADDR", INFOTOK_STARTADDR }, + { "STARTADDR", INFOTOK_STARTADDR }, + { "TEXTCOL", INFOTOK_TEXT_COLUMN }, + { "TEXTCOLUMN", INFOTOK_TEXT_COLUMN }, }; /* Skip the token */ @@ -110,6 +118,22 @@ static void GlobalSection (void) /* Look at the token */ switch (InfoTok) { + case INFOTOK_ARGUMENT_COLUMN: + InfoNextTok (); + InfoAssureInt (); + InfoRangeCheck (MIN_ACOL, MAX_ACOL); + ACol = InfoIVal; + InfoNextTok (); + break; + + case INFOTOK_COMMENT_COLUMN: + InfoNextTok (); + InfoAssureInt (); + InfoRangeCheck (MIN_CCOL, MAX_CCOL); + CCol = InfoIVal; + InfoNextTok (); + break; + case INFOTOK_COMMENTS: InfoNextTok (); InfoAssureInt (); @@ -172,6 +196,14 @@ static void GlobalSection (void) InfoNextTok (); break; + case INFOTOK_MNEMONIC_COLUMN: + InfoNextTok (); + InfoAssureInt (); + InfoRangeCheck (MIN_MCOL, MAX_MCOL); + MCol = InfoIVal; + InfoNextTok (); + break; + case INFOTOK_OUTPUTNAME: InfoNextTok (); InfoAssureStr (); @@ -200,6 +232,17 @@ static void GlobalSection (void) InfoNextTok (); break; + case INFOTOK_TEXT_COLUMN: + InfoNextTok (); + InfoAssureInt (); + InfoRangeCheck (MIN_TCOL, MAX_TCOL); + TCol = InfoIVal; + InfoNextTok (); + break; + + default: + Internal ("Unexpected token: %u", InfoTok); + } /* Directive is followed by a semicolon */ @@ -332,6 +375,9 @@ static void RangeSection (void) } InfoNextTok (); break; + + default: + Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ @@ -455,6 +501,8 @@ static void LabelSection (void) InfoNextTok (); break; + default: + Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ @@ -566,6 +614,9 @@ static void AsmIncSection (void) IgnoreUnknown = (InfoTok != INFOTOK_FALSE); InfoNextTok (); break; + + default: + Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ @@ -628,6 +679,9 @@ static void InfoParse (void) case INFOTOK_ASMINC: AsmIncSection (); break; + + default: + Internal ("Unexpected token: %u", InfoTok); } /* Semicolon expected */ diff --git a/src/da65/main.c b/src/da65/main.c index 34b48f4bb..de77fa730 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -84,6 +84,8 @@ static void Usage (void) " -V\t\t\tPrint the disassembler version\n" "\n" "Long options:\n" + " --argument-column n\tSpecify argument start column\n" + " --comment-column n\tSpecify comment start column\n" " --comments n\t\tSet the comment level for the output\n" " --cpu type\t\tSet cpu type\n" " --debug-info\t\tAdd debug info to object file\n" @@ -92,8 +94,10 @@ static void Usage (void) " --hexoffs\t\tUse hexadecimal label offsets\n" " --info name\t\tSpecify an info file\n" " --label-break n\tAdd newline if label exceeds length n\n" + " --mnemonic-column n\tSpecify mnemonic start column\n" " --pagelength n\tSet the page length for the listing\n" " --start-addr addr\tSet the start/load address\n" + " --text-column n\tSpecify text start column\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the disassembler version\n", ProgName); @@ -101,6 +105,19 @@ static void Usage (void) +static void RangeCheck (const char* Opt, unsigned long Val, + unsigned long Min, unsigned long Max) +/* Do a range check for the given option and abort if there's a range + * error. + */ +{ + if (Val < Min || Val > Max) { + Error ("Argument for %s outside valid range (%ld-%ld)", Opt, Min, Max); + } +} + + + static unsigned long CvtNumber (const char* Arg, const char* Number) /* Convert a number from a string. Allow '$' and '0x' prefixes for hex * numbers. @@ -129,6 +146,51 @@ static unsigned long CvtNumber (const char* Arg, const char* Number) +static void OptArgumentColumn (const char* Opt, const char* Arg) +/* Handle the --argument-column option */ +{ + /* Convert the argument to a number */ + unsigned long Val = CvtNumber (Opt, Arg); + + /* Check for a valid range */ + RangeCheck (Opt, Val, MIN_ACOL, MAX_ACOL); + + /* Use the value */ + ACol = (unsigned char) Val; +} + + + +static void OptBytesPerLine (const char* Opt, const char* Arg) +/* Handle the --bytes-per-line option */ +{ + /* Convert the argument to a number */ + unsigned long Val = CvtNumber (Opt, Arg); + + /* Check for a valid range */ + RangeCheck (Opt, Val, MIN_BYTESPERLINE, MAX_BYTESPERLINE); + + /* Use the value */ + BytesPerLine = (unsigned char) Val; +} + + + +static void OptCommentColumn (const char* Opt, const char* Arg) +/* Handle the --comment-column option */ +{ + /* Convert the argument to a number */ + unsigned long Val = CvtNumber (Opt, Arg); + + /* Check for a valid range */ + RangeCheck (Opt, Val, MIN_CCOL, MAX_CCOL); + + /* Use the value */ + CCol = (unsigned char) Val; +} + + + static void OptComments (const char* Opt, const char* Arg) /* Handle the --comments option */ { @@ -136,10 +198,7 @@ static void OptComments (const char* Opt, const char* Arg) unsigned long Val = CvtNumber (Opt, Arg); /* Check for a valid range */ - if (Val > MAX_COMMENTS) { - Error ("Argument for %s outside valid range (%d-%d)", - Opt, MIN_COMMENTS, MAX_COMMENTS); - } + RangeCheck (Opt, Val, MIN_COMMENTS, MAX_COMMENTS); /* Use the value */ Comments = (unsigned char) Val; @@ -209,10 +268,7 @@ static void OptLabelBreak (const char* Opt, const char* Arg) unsigned long Val = CvtNumber (Opt, Arg); /* Check for a valid range */ - if (Val >= UCHAR_MAX) { - Error ("Argument for %s out of valid range (%d)", - Opt, UCHAR_MAX); - } + RangeCheck (Opt, Val, MIN_LABELBREAK, MAX_LABELBREAK); /* Use the value */ LBreak = (unsigned char) Val; @@ -220,12 +276,27 @@ static void OptLabelBreak (const char* Opt, const char* Arg) +static void OptMnemonicColumn (const char* Opt, const char* Arg) +/* Handle the --mnemonic-column option */ +{ + /* Convert the argument to a number */ + unsigned long Val = CvtNumber (Opt, Arg); + + /* Check for a valid range */ + RangeCheck (Opt, Val, MIN_MCOL, MAX_MCOL); + + /* Use the value */ + MCol = (unsigned char) Val; +} + + + static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --pagelength option */ { int Len = atoi (Arg); - if (Len != 0 && (Len < MIN_PAGE_LEN || Len > MAX_PAGE_LEN)) { - AbEnd ("Invalid page length: %d", Len); + if (Len != 0) { + RangeCheck (Opt, Len, MIN_PAGE_LEN, MAX_PAGE_LEN); } PageLength = Len; } @@ -240,6 +311,21 @@ static void OptStartAddr (const char* Opt, const char* Arg) +static void OptTextColumn (const char* Opt, const char* Arg) +/* Handle the --text-column option */ +{ + /* Convert the argument to a number */ + unsigned long Val = CvtNumber (Opt, Arg); + + /* Check for a valid range */ + RangeCheck (Opt, Val, MIN_TCOL, MAX_TCOL); + + /* Use the value */ + TCol = (unsigned char) Val; +} + + + static void OptVerbose (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Increase verbosity */ @@ -412,16 +498,21 @@ int main (int argc, char* argv []) { /* Program long options */ static const LongOpt OptTab[] = { + { "--argument-column", 1, OptArgumentColumn }, + { "--bytes-per-line", 1, OptBytesPerLine }, + { "--comment-column", 1, OptCommentColumn }, { "--comments", 1, OptComments }, - { "--cpu", 1, OptCPU }, + { "--cpu", 1, OptCPU }, { "--debug-info", 0, OptDebugInfo }, - { "--formfeeds", 0, OptFormFeeds }, - { "--help", 0, OptHelp }, - { "--hexoffs", 0, OptHexOffs }, + { "--formfeeds", 0, OptFormFeeds }, + { "--help", 0, OptHelp }, + { "--hexoffs", 0, OptHexOffs }, { "--info", 1, OptInfo }, { "--label-break", 1, OptLabelBreak }, + { "--mnemonic-column", 1, OptMnemonicColumn }, { "--pagelength", 1, OptPageLength }, { "--start-addr", 1, OptStartAddr }, + { "--text-column", 1, OptTextColumn }, { "--verbose", 0, OptVerbose }, { "--version", 0, OptVersion }, }; @@ -503,6 +594,20 @@ int main (int argc, char* argv []) AbEnd ("No input file"); } + /* Check the formatting options for reasonable values. Note: We will not + * really check that they make sense, just that they aren't complete + * garbage. + */ + if (MCol >= ACol) { + AbEnd ("mnemonic-column value must be smaller than argument-column value"); + } + if (ACol >= CCol) { + AbEnd ("argument-column value must be smaller than comment-column value"); + } + if (CCol >= TCol) { + AbEnd ("comment-column value must be smaller than text-column value"); + } + /* If no CPU given, use the default CPU */ if (CPU == CPU_UNKNOWN) { CPU = CPU_6502; diff --git a/src/da65/output.c b/src/da65/output.c index 864114040..5305409c6 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -169,7 +169,7 @@ void DefLabel (const char* Name) /* If the label is longer than the configured maximum, or if it runs into * the opcode column, start a new line. */ - if (Col > LBreak+2 || Col > MIndent) { + if (Col > LBreak+2 || Col > MCol) { LineFeed (); } } @@ -183,14 +183,14 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs) { if (Pass == PassCount) { Output ("%s", Name); - Indent (AIndent); + Indent (ACol); if (UseHexOffs) { Output (":= * + $%04X", Offs); } else { Output (":= * + %u", Offs); } if (Comment) { - Indent (CIndent); + Indent (CCol); Output ("; %s", Comment); } LineFeed (); @@ -204,10 +204,10 @@ void DefineConst (const char* Name, const char* Comment, unsigned Addr) { if (Pass == PassCount) { Output ("%s", Name); - Indent (AIndent); + Indent (ACol); Output (":= $%04X", Addr); if (Comment) { - Indent (CIndent); + Indent (CCol); Output ("; %s", Comment); } LineFeed (); @@ -221,9 +221,9 @@ void DataByteLine (unsigned ByteCount) { unsigned I; - Indent (MIndent); + Indent (MCol); Output (".byte"); - Indent (AIndent); + Indent (ACol); for (I = 0; I < ByteCount; ++I) { if (I > 0) { Output (",$%02X", CodeBuf[PC+I]); @@ -242,9 +242,9 @@ void DataDByteLine (unsigned ByteCount) { unsigned I; - Indent (MIndent); + Indent (MCol); Output (".dbyte"); - Indent (AIndent); + Indent (ACol); for (I = 0; I < ByteCount; I += 2) { if (I > 0) { Output (",$%04X", GetCodeDByte (PC+I)); @@ -263,9 +263,9 @@ void DataWordLine (unsigned ByteCount) { unsigned I; - Indent (MIndent); + Indent (MCol); Output (".word"); - Indent (AIndent); + Indent (ACol); for (I = 0; I < ByteCount; I += 2) { if (I > 0) { Output (",$%04X", GetCodeWord (PC+I)); @@ -284,9 +284,9 @@ void DataDWordLine (unsigned ByteCount) { unsigned I; - Indent (MIndent); + Indent (MCol); Output (".dword"); - Indent (AIndent); + Indent (ACol); for (I = 0; I < ByteCount; I += 4) { if (I > 0) { Output (",$%08lX", GetCodeDWord (PC+I)); @@ -326,14 +326,14 @@ void LineComment (unsigned PC, unsigned Count) unsigned I; if (Pass == PassCount && Comments >= 2) { - Indent (CIndent); + Indent (CCol); Output ("; %04X", PC); if (Comments >= 3) { for (I = 0; I < Count; ++I) { Output (" %02X", CodeBuf [PC+I]); } if (Comments >= 4) { - Indent (TIndent); + Indent (TCol); for (I = 0; I < Count; ++I) { unsigned char C = CodeBuf [PC+I]; if (!isprint (C)) { @@ -352,9 +352,9 @@ void OutputSettings (void) /* Output CPU and other settings */ { LineFeed (); - Indent (MIndent); + Indent (MCol); Output (".setcpu"); - Indent (AIndent); + Indent (ACol); Output ("\"%s\"", CPUNames[CPU]); LineFeed (); LineFeed (); diff --git a/src/da65/scanner.h b/src/da65/scanner.h index fca05ed42..0c1c73ef2 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -67,16 +67,20 @@ typedef enum token_t { INFOTOK_ASMINC, /* Global section */ + INFOTOK_ARGUMENT_COLUMN, + INFOTOK_COMMENT_COLUMN, INFOTOK_COMMENTS, INFOTOK_CPU, INFOTOK_HEXOFFS, INFOTOK_INPUTNAME, INFOTOK_INPUTOFFS, INFOTOK_INPUTSIZE, - INFOTOK_LABELBREAK, + INFOTOK_LABELBREAK, + INFOTOK_MNEMONIC_COLUMN, INFOTOK_OUTPUTNAME, INFOTOK_PAGELENGTH, - INFOTOK_STARTADDR, + INFOTOK_STARTADDR, + INFOTOK_TEXT_COLUMN, /* Range section */ INFOTOK_START, -- 2.39.5