From e3d3a43c3c457e4a369c9016d87c4cde896fe879 Mon Sep 17 00:00:00 2001 From: cuz Date: Sat, 23 Aug 2003 09:20:33 +0000 Subject: [PATCH] New features: DByteTable, Comments git-svn-id: svn://svn.cc65.org/cc65/trunk@2409 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/da65/attrtab.c | 44 +++++++++++++++-- src/da65/attrtab.h | 24 ++++++---- src/da65/code.c | 10 ++++ src/da65/code.h | 3 ++ src/da65/data.c | 16 ++++++- src/da65/data.h | 3 ++ src/da65/global.c | 3 ++ src/da65/global.h | 5 ++ src/da65/infofile.c | 113 ++++++++++++++++++++++++-------------------- src/da65/main.c | 31 ++++++++++-- src/da65/output.c | 30 ++++++++++-- src/da65/output.h | 3 ++ src/da65/scanner.h | 4 +- 13 files changed, 214 insertions(+), 75 deletions(-) diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index 247e645c1..c59ca5633 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2000-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -112,7 +112,7 @@ void MarkAddr (unsigned Addr, attr_t Attr) const char* MakeLabelName (unsigned Addr) /* Make the default label name from the given address and return it in a * static buffer. - */ + */ { static char LabelBuf [32]; xsprintf (LabelBuf, sizeof (LabelBuf), "L%04X", Addr); @@ -145,6 +145,40 @@ void AddLabel (unsigned Addr, attr_t Attr, const char* Name) +void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count) +/* Add an external label for a range. The first entry gets the label "Name" + * while the others get "Name+offs". + */ +{ + /* Define the label */ + AddLabel (Addr, atExtLabel, Name); + + /* Define dependent labels if necessary */ + if (Count > 1) { + unsigned Offs; + + /* Allocate memory for the dependent label names */ + unsigned NameLen = strlen (Name); + char* DepName = xmalloc (NameLen + 7); + char* DepOffs = DepName + NameLen + 1; + + /* Copy the original name into the buffer */ + memcpy (DepName, Name, NameLen); + DepName[NameLen] = '+'; + + /* Define the labels */ + for (Offs = 1; Offs < Count; ++Offs) { + sprintf (DepOffs, "%u", Offs); + AddLabel (Addr + Offs, atDepLabel, DepName); + } + + /* Free the name buffer */ + xfree (DepName); + } +} + + + int HaveLabel (unsigned Addr) /* Check if there is a label for the given address */ { diff --git a/src/da65/attrtab.h b/src/da65/attrtab.h index 50d39b016..828cde128 100644 --- a/src/da65/attrtab.h +++ b/src/da65/attrtab.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2000-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -51,11 +51,12 @@ typedef enum attr_t { atCode = 0x01, atIllegal = 0x02, atByteTab = 0x03, /* Same as illegal */ - atWordTab = 0x04, - atDWordTab = 0x05, - atAddrTab = 0x06, - atRtsTab = 0x07, - atTextTab = 0x08, + atDByteTab = 0x04, + atWordTab = 0x05, + atDWordTab = 0x06, + atAddrTab = 0x07, + atRtsTab = 0x08, + atTextTab = 0x09, /* Label flags */ atNoLabel = 0x00, /* No label for this address */ @@ -89,6 +90,11 @@ const char* MakeLabelName (unsigned Addr); void AddLabel (unsigned Addr, attr_t Attr, const char* Name); /* Add a label */ +void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count); +/* Add an external label for a range. The first entry gets the label "Name" + * while the others get "Name+offs". + */ + int HaveLabel (unsigned Addr); /* Check if there is a label for the given address */ diff --git a/src/da65/code.c b/src/da65/code.c index 72246b387..cef4ef2dd 100644 --- a/src/da65/code.c +++ b/src/da65/code.c @@ -139,6 +139,16 @@ unsigned char GetCodeByte (unsigned Addr) +unsigned GetCodeDByte (unsigned Addr) +/* Get a dbyte from the given address */ +{ + unsigned Lo = GetCodeByte (Addr); + unsigned Hi = GetCodeByte (Addr+1); + return (Lo <<8) | Hi; +} + + + unsigned GetCodeWord (unsigned Addr) /* Get a word from the given address */ { diff --git a/src/da65/code.h b/src/da65/code.h index 3a1536437..59e77db9b 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -63,6 +63,9 @@ void LoadCode (void); unsigned char GetCodeByte (unsigned Addr); /* Get a byte from the given address */ +unsigned GetCodeDByte (unsigned Addr); +/* Get a dbyte from the given address */ + unsigned GetCodeWord (unsigned Addr); /* Get a word from the given address */ diff --git a/src/da65/data.c b/src/da65/data.c index d55dda050..0928985c4 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -128,6 +128,15 @@ unsigned ByteTable (void) +unsigned DByteTable (void) +/* Output a table of dbytes */ +{ + /* Call the low level function */ + return DoTable (atDByteTab, 2, DataDByteLine); +} + + + unsigned WordTable (void) /* Output a table of words */ { @@ -154,7 +163,7 @@ unsigned AddrTable (void) /* Count how many bytes may be output. */ unsigned Count = GetSpan (atAddrTab); - /* Handle Count == 1 ### */ + /* Handle Count == 1 */ if (Count == 1) { ByteTable (); } @@ -214,7 +223,10 @@ unsigned RtsTable (void) /* Count how many bytes may be output. */ unsigned Count = GetSpan (atRtsTab); - /* Need to handle Count == 1 here!!! ### */ + /* Handle Count == 1 */ + if (Count == 1) { + ByteTable (); + } /* Make the given number even */ Count &= ~1U; diff --git a/src/da65/data.h b/src/da65/data.h index 997c51283..a6603fa03 100644 --- a/src/da65/data.h +++ b/src/da65/data.h @@ -47,6 +47,9 @@ unsigned ByteTable (void); /* Output a table of bytes */ +unsigned DByteTable (void); +/* Output a table of dbytes */ + unsigned WordTable (void); /* Output a table of words */ diff --git a/src/da65/global.c b/src/da65/global.c index 32d24738b..2742cb8dc 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -60,6 +60,9 @@ long StartAddr = -1; /* Start/load address of the program */ /* Stuff needed by many routines */ unsigned char Pass = 0; /* Disassembler pass */ +/* Comments */ +unsigned char Comments = 0; /* Add which comments to the output? */ + /* Page formatting */ unsigned PageLength = 0; /* Length of a listing page */ unsigned MIndent = 9; /* Mnemonic indent */ diff --git a/src/da65/global.h b/src/da65/global.h index 2e8be8a57..96f11c912 100644 --- a/src/da65/global.h +++ b/src/da65/global.h @@ -62,6 +62,11 @@ extern long StartAddr; /* Start/load address of the program */ /* Stuff needed by many routines */ extern unsigned char Pass; /* Disassembler pass */ +/* Comments */ +#define MIN_COMMENTS 0 +#define MAX_COMMENTS 4 +extern unsigned char Comments; /* Add which comments to the output? */ + /* Page formatting */ #define MIN_PAGE_LEN 32 #define MAX_PAGE_LEN 127 diff --git a/src/da65/infofile.c b/src/da65/infofile.c index 8cf95fcaf..4f32661ba 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -67,6 +67,7 @@ static void GlobalSection (void) /* Parse a global section */ { static const IdentTok GlobalDefs[] = { + { "COMMENTS", INFOTOK_COMMENTS }, { "CPU", INFOTOK_CPU }, { "INPUTNAME", INFOTOK_INPUTNAME }, { "OUTPUTNAME", INFOTOK_OUTPUTNAME }, @@ -89,6 +90,14 @@ static void GlobalSection (void) /* Look at the token */ switch (InfoTok) { + case INFOTOK_COMMENTS: + InfoNextTok (); + InfoAssureInt (); + InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS); + Comments = InfoIVal; + InfoNextTok (); + break; + case INFOTOK_CPU: InfoNextTok (); InfoAssureStr (); @@ -155,35 +164,39 @@ static void RangeSection (void) /* Parse a range section */ { static const IdentTok RangeDefs[] = { - { "START", INFOTOK_START }, { "END", INFOTOK_END }, - { "TYPE", INFOTOK_TYPE }, + { "NAME", INFOTOK_NAME }, + { "START", INFOTOK_START }, + { "TYPE", INFOTOK_TYPE }, }; static const IdentTok TypeDefs[] = { - { "CODE", INFOTOK_CODE }, - { "BYTETABLE", INFOTOK_BYTETAB }, - { "WORDTABLE", INFOTOK_WORDTAB }, - { "DWORDTABLE", INFOTOK_DWORDTAB }, - { "ADDRTABLE", INFOTOK_ADDRTAB }, - { "RTSTABLE", INFOTOK_RTSTAB }, - { "TEXTTABLE", INFOTOK_TEXTTAB }, + { "CODE", INFOTOK_CODE }, + { "BYTETABLE", INFOTOK_BYTETAB }, + { "DBYTETABLE", INFOTOK_DBYTETAB }, + { "WORDTABLE", INFOTOK_WORDTAB }, + { "DWORDTABLE", INFOTOK_DWORDTAB }, + { "ADDRTABLE", INFOTOK_ADDRTAB }, + { "RTSTABLE", INFOTOK_RTSTAB }, + { "TEXTTABLE", INFOTOK_TEXTTAB }, }; /* Which values did we get? */ enum { - tNone = 0x00, - tStart = 0x01, - tEnd = 0x02, - tType = 0x04, - tAll = 0x07 - } Needed = tNone; + tNone = 0x00, + tStart = 0x01, + tEnd = 0x02, + tType = 0x04, + tName = 0x08, + tNeeded = (tStart | tEnd | tType) + } Attributes = tNone; /* Locals - initialize to avoid gcc warnings */ unsigned Start = 0; unsigned End = 0; unsigned char Type = 0; + char* Name = 0; /* Skip the token */ InfoNextTok (); @@ -200,21 +213,35 @@ static void RangeSection (void) /* Look at the token */ switch (InfoTok) { - case INFOTOK_START: - InfoNextTok (); + case INFOTOK_END: + InfoNextTok (); InfoAssureInt (); InfoRangeCheck (0x0000, 0xFFFF); - Start = InfoIVal; - Needed |= tStart; + End = InfoIVal; + Attributes |= tEnd; InfoNextTok (); break; - case INFOTOK_END: - InfoNextTok (); + case INFOTOK_NAME: + InfoNextTok (); + if (Name) { + InfoError ("Name already given"); + } + InfoAssureStr (); + if (InfoSVal[0] == '\0') { + InfoError ("Name may not be empty"); + } + Name = xstrdup (InfoSVal); + Attributes |= tName; + InfoNextTok (); + break; + + case INFOTOK_START: + InfoNextTok (); InfoAssureInt (); InfoRangeCheck (0x0000, 0xFFFF); - End = InfoIVal; - Needed |= tEnd; + Start = InfoIVal; + Attributes |= tStart; InfoNextTok (); break; @@ -224,13 +251,14 @@ static void RangeSection (void) switch (InfoTok) { case INFOTOK_CODE: Type = atCode; break; case INFOTOK_BYTETAB: Type = atByteTab; break; + case INFOTOK_DBYTETAB: Type = atDByteTab; break; case INFOTOK_WORDTAB: Type = atWordTab; break; case INFOTOK_DWORDTAB: Type = atDWordTab; break; case INFOTOK_ADDRTAB: Type = atAddrTab; break; case INFOTOK_RTSTAB: Type = atRtsTab; break; case INFOTOK_TEXTTAB: Type = atTextTab; break; } - Needed |= tType; + Attributes |= tType; InfoNextTok (); break; } @@ -241,7 +269,7 @@ static void RangeSection (void) } /* Did we get all required values? */ - if (Needed != tAll) { + if ((Attributes & tNeeded) != tNeeded) { InfoError ("Required values missing from this section"); } @@ -253,6 +281,14 @@ static void RangeSection (void) /* Set the range */ MarkRange (Start, End, Type); + /* Do we have a label? */ + if (Attributes & tName) { + /* Define a label for the table */ + AddLabel (Start, atExtLabel, Name); + /* Delete the name */ + xfree (Name); + } + /* Consume the closing brace */ InfoConsumeRCurly (); } @@ -347,31 +383,8 @@ static void LabelSection (void) InfoError ("Label for address $%04lX already defined", Value); } - /* Define the label */ - AddLabel ((unsigned) Value, atExtLabel, Name); - - /* Define dependent labels if necessary */ - if (Size > 1) { - unsigned Offs; - - /* Allocate memory for the dependent label names */ - unsigned NameLen = strlen (Name); - char* DepName = xmalloc (NameLen + 7); - char* DepOffs = DepName + NameLen + 1; - - /* Copy the original name into the buffer */ - memcpy (DepName, Name, NameLen); - DepName[NameLen] = '+'; - - /* Define the labels */ - for (Offs = 1; Offs < (unsigned) Size; ++Offs) { - sprintf (DepOffs, "%u", Offs); - AddLabel ((unsigned) Value+Offs, atDepLabel, DepName); - } - - /* Free the name buffer */ - xfree (DepName); - } + /* Define the label(s) */ + AddExtLabelRange ((unsigned) Value, Name, Size); /* Delete the dynamically allocated memory for Name */ xfree (Name); diff --git a/src/da65/main.c b/src/da65/main.c index d4623216e..3d3d96d9a 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -82,6 +82,7 @@ static void Usage (void) " -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" @@ -103,13 +104,14 @@ static unsigned long CvtNumber (const char* Arg, const char* Number) { unsigned long Val; int Converted; + char BoundsCheck; /* Convert */ if (*Number == '$') { ++Number; - Converted = sscanf (Number, "%lx", &Val); + Converted = sscanf (Number, "%lx%c", &Val, &BoundsCheck); } else { - Converted = sscanf (Number, "%li", (long*)&Val); + Converted = sscanf (Number, "%li%c", (long*)&Val, &BoundsCheck); } /* Check if we do really have a number */ @@ -123,6 +125,24 @@ static unsigned long CvtNumber (const char* Arg, const char* Number) +static void OptComments (const char* Opt, const char* Arg) +/* Handle the --comments option */ +{ + /* Convert the argument to a number */ + 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); + } + + /* Use the value */ + Comments = (unsigned char) Val; +} + + + static void OptCPU (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --cpu option */ { @@ -134,7 +154,7 @@ static void OptCPU (const char* Opt attribute ((unused)), const char* Arg) static void OptDebugInfo (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Add debug info to the object file */ { DebugInfo = 1; @@ -258,6 +278,10 @@ static void OneOpcode (unsigned RemainingBytes) ByteTable (); break; + case atDByteTab: + DByteTable (); + break; + case atWordTab: WordTable (); break; @@ -326,6 +350,7 @@ int main (int argc, char* argv []) { /* Program long options */ static const LongOpt OptTab[] = { + { "--comments", 1, OptComments }, { "--cpu", 1, OptCPU }, { "--debug-info", 0, OptDebugInfo }, { "--formfeeds", 0, OptFormFeeds }, diff --git a/src/da65/output.c b/src/da65/output.c index ac4108f9e..f8a5aeac2 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -41,7 +41,6 @@ /* common */ #include "cpu.h" -#include "print.h" #include "version.h" /* da65 */ @@ -188,6 +187,27 @@ void DataByteLine (unsigned ByteCount) +void DataDByteLine (unsigned ByteCount) +/* Output a line with dbytes */ +{ + unsigned I; + + Indent (MIndent); + Output (".dbyte"); + Indent (AIndent); + for (I = 0; I < ByteCount; I += 2) { + if (I > 0) { + Output (",$%04X", GetCodeDByte (PC+I)); + } else { + Output ("$%04X", GetCodeDByte (PC+I)); + } + } + LineComment (PC, ByteCount); + LineFeed (); +} + + + void DataWordLine (unsigned ByteCount) /* Output a line with words */ { @@ -233,7 +253,7 @@ void DataDWordLine (unsigned ByteCount) void SeparatorLine (void) /* Print a separator line */ { - if (Pass == PassCount && Verbosity >= 1) { + if (Pass == PassCount && Comments >= 1) { Output ("; ----------------------------------------------------------------------------"); LineFeed (); } @@ -246,14 +266,14 @@ void LineComment (unsigned PC, unsigned Count) { unsigned I; - if (Pass == PassCount && Verbosity >= 2) { + if (Pass == PassCount && Comments >= 2) { Indent (CIndent); Output ("; %04X", PC); - if (Verbosity >= 3) { + if (Comments >= 3) { for (I = 0; I < Count; ++I) { Output (" %02X", CodeBuf [PC+I]); } - if (Verbosity >= 4) { + if (Comments >= 4) { Indent (TIndent); for (I = 0; I < Count; ++I) { unsigned char C = CodeBuf [PC+I]; diff --git a/src/da65/output.h b/src/da65/output.h index 0d1269b7d..8a44f9316 100644 --- a/src/da65/output.h +++ b/src/da65/output.h @@ -73,6 +73,9 @@ void OneDataByte (void); void DataByteLine (unsigned ByteCount); /* Output a line with bytes */ +void DataDByteLine (unsigned ByteCount); +/* Output a line with dbytes */ + void DataWordLine (unsigned ByteCount); /* Output a line with words */ diff --git a/src/da65/scanner.h b/src/da65/scanner.h index d26f191e2..a8af803b9 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -65,6 +65,7 @@ typedef enum token_t { INFOTOK_LABEL, /* Global section */ + INFOTOK_COMMENTS, INFOTOK_CPU, INFOTOK_INPUTNAME, INFOTOK_OUTPUTNAME, @@ -77,7 +78,8 @@ typedef enum token_t { INFOTOK_TYPE, INFOTOK_CODE, - INFOTOK_BYTETAB, + INFOTOK_BYTETAB, + INFOTOK_DBYTETAB, INFOTOK_WORDTAB, INFOTOK_DWORDTAB, INFOTOK_ADDRTAB, -- 2.39.5