X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fda65%2Fmain.c;h=aa48629ba5a8483f9c33e25f8738b1c93040c672;hb=bee54df02967b774c485b0a7fa703b5a76345d4e;hp=94e535cb31634a49a1bd2ede7db4afcc51196993;hpb=1b311d932d6de5bdea36ec7bad53c43cfdda2cdf;p=cc65 diff --git a/src/da65/main.c b/src/da65/main.c index 94e535cb3..aa48629ba 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -37,6 +37,7 @@ #include #include #include +#include #include /* common */ @@ -50,10 +51,12 @@ /* da65 */ #include "attrtab.h" #include "code.h" +#include "comments.h" #include "data.h" #include "error.h" #include "global.h" #include "infofile.h" +#include "labels.h" #include "opctable.h" #include "output.h" #include "scanner.h" @@ -69,30 +72,48 @@ static void Usage (void) /* Print usage information and exit */ { - fprintf (stderr, - "Usage: %s [options] [inputfile]\n" - "Short options:\n" - " -g\t\t\tAdd debug info to object file\n" - " -h\t\t\tHelp (this text)\n" - " -i name\t\tSpecify an info file\n" - " -o name\t\tName the output file\n" - " -v\t\t\tIncrease verbosity\n" - " -F\t\t\tAdd formfeeds to the output\n" - " -S addr\t\tSet the start/load address\n" - " -V\t\t\tPrint the disassembler version\n" - "\n" - "Long options:\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" - " --formfeeds\t\tAdd formfeeds to the output\n" - " --help\t\tHelp (this text)\n" - " --info name\t\tSpecify an info file\n" - " --pagelength n\tSet the page length for the listing\n" - " --start-addr addr\tSet the start/load address\n" - " --verbose\t\tIncrease verbosity\n" - " --version\t\tPrint the disassembler version\n", - ProgName); + printf ("Usage: %s [options] [inputfile]\n" + "Short options:\n" + " -g\t\t\tAdd debug info to object file\n" + " -h\t\t\tHelp (this text)\n" + " -i name\t\tSpecify an info file\n" + " -o name\t\tName the output file\n" + " -v\t\t\tIncrease verbosity\n" + " -F\t\t\tAdd formfeeds to the output\n" + " -S addr\t\tSet the start/load address\n" + " -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" + " --formfeeds\t\tAdd formfeeds to the output\n" + " --help\t\tHelp (this text)\n" + " --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); +} + + + +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); + } } @@ -125,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 */ { @@ -132,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; @@ -181,6 +244,15 @@ static void OptHelp (const char* Opt attribute ((unused)), +static void OptHexOffs (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Handle the --hexoffs option */ +{ + UseHexOffs = 1; +} + + + static void OptInfo (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --info option */ { @@ -189,12 +261,42 @@ static void OptInfo (const char* Opt attribute ((unused)), const char* Arg) +static void OptLabelBreak (const char* Opt, const char* Arg) +/* Handle the --label-break option */ +{ + /* Convert the argument to a number */ + unsigned long Val = CvtNumber (Opt, Arg); + + /* Check for a valid range */ + RangeCheck (Opt, Val, MIN_LABELBREAK, MAX_LABELBREAK); + + /* Use the value */ + LBreak = (unsigned char) Val; +} + + + +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; } @@ -209,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 */ @@ -223,8 +340,8 @@ static void OptVersion (const char* Opt attribute ((unused)), /* Print the disassembler version */ { fprintf (stderr, - "da65 V%u.%u.%u - (C) Copyright 2000 Ullrich von Bassewitz\n", - VER_MAJOR, VER_MINOR, VER_PATCH); + "da65 V%s - (C) Copyright 2000-2009, Ullrich von Bassewitz\n", + GetVersionAsString ()); } @@ -241,11 +358,15 @@ static void OneOpcode (unsigned RemainingBytes) /* Get the output style for the current PC */ attr_t Style = GetStyleAttr (PC); - /* If we have a label at this address, output the label, provided that - * we aren't in a skip area. + /* If we have a label at this address, output the label and an attached + * comment, provided that we aren't in a skip area. */ if (Style != atSkip && MustDefLabel (PC)) { - DefLabel (GetLabel (PC)); + const char* Comment = GetComment (PC); + if (Comment) { + UserComment (Comment); + } + DefLabel (GetLabelName (PC)); } /* Check... @@ -256,14 +377,17 @@ static void OneOpcode (unsigned RemainingBytes) */ if (Style == atDefault) { if (D->Size > RemainingBytes) { - MarkAddr (PC, atIllegal); + Style = atIllegal; + MarkAddr (PC, Style); } else if (D->Flags & flIllegal) { - MarkAddr (PC, atIllegal); + Style = atIllegal; + MarkAddr (PC, Style); } else { unsigned I; for (I = 1; I < D->Size; ++I) { - if (HaveLabel (PC+I)) { - MarkAddr (PC, atIllegal); + if (HaveLabel (PC+I) || HaveSegmentChange (PC+I)) { + Style = atIllegal; + MarkAddr (PC, Style); break; } } @@ -274,11 +398,27 @@ static void OneOpcode (unsigned RemainingBytes) switch (Style) { case atDefault: - case atCode: D->Handler (D); PC += D->Size; break; + case atCode: + /* Beware: If we don't have enough bytes left to disassemble the + * following insn, fall through to byte mode. + */ + if (D->Size <= RemainingBytes) { + /* Output labels within the next insn */ + unsigned I; + for (I = 1; I < D->Size; ++I) { + ForwardLabel (I); + } + /* Output the insn */ + D->Handler (D); + PC += D->Size; + break; + } + /* FALLTHROUGH */ + case atByteTab: ByteTable (); break; @@ -298,7 +438,7 @@ static void OneOpcode (unsigned RemainingBytes) case atAddrTab: AddrTable (); break; - + case atRtsTab: RtsTable (); break; @@ -359,19 +499,27 @@ 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 }, + { "--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 }, + { "--start-addr", 1, OptStartAddr }, + { "--text-column", 1, OptTextColumn }, { "--verbose", 0, OptVerbose }, { "--version", 0, OptVersion }, }; unsigned I; + time_t T; /* Initialize the cmdline module */ InitCmdLine (&argc, &argv, "da65"); @@ -447,9 +595,18 @@ int main (int argc, char* argv []) AbEnd ("No input file"); } - /* Make the output file name from the input file name if none was given */ - if (OutFile == 0) { - OutFile = MakeFilename (InFile, OutExt); + /* 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 */ @@ -457,6 +614,12 @@ int main (int argc, char* argv []) CPU = CPU_6502; } + /* Get the current time and convert it to string so it can be used in + * the output page headers. + */ + T = time (0); + strftime (Now, sizeof (Now), "%Y-%m-%d %H:%M:%S", localtime (&T)); + /* Load the input file */ LoadCode ();