diff --git a/doc/da65.sgml b/doc/da65.sgml
index 9513ab9f3..343bbee83 100644
--- a/doc/da65.sgml
+++ b/doc/da65.sgml
@@ -270,9 +270,9 @@ following attributes are recognized:
INPUTSIZE
- INPUTSIZE is followed by a numerical value that gives the amount of data
- to read from the input file. Data beyond OUTPUTNAME
@@ -363,6 +363,14 @@ following attributes are recognized:
TEXTTABLE
The range consists of readable text.
+
+ SKIP
+ The range is simply ignored when generating the output file. Please note
+ that this means that reassembling the output file will
diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c
index c59ca5633..005f28477 100644
--- a/src/da65/attrtab.c
+++ b/src/da65/attrtab.c
@@ -260,17 +260,28 @@ void DefOutOfRangeLabels (void)
SeparatorLine ();
/* Low range */
- for (Addr = 0; Addr < CodeStart; ++Addr) {
+ Addr = 0;
+ while (Addr < CodeStart) {
if (MustDefLabel (Addr)) {
DefineConst (Addr);
}
+ ++Addr;
+ }
+
+ /* Skip areas in code range */
+ while (Addr <= CodeEnd) {
+ if ((AttrTab[Addr] & atStyleMask) == atSkip && MustDefLabel (Addr)) {
+ DefineConst (Addr);
+ }
+ ++Addr;
}
/* High range */
- for (Addr = CodeEnd+1; Addr < 0x10000; ++Addr) {
+ while (Addr < 0x10000) {
if (MustDefLabel (Addr)) {
DefineConst (Addr);
}
+ ++Addr;
}
SeparatorLine ();
diff --git a/src/da65/attrtab.h b/src/da65/attrtab.h
index 828cde128..69c8ee298 100644
--- a/src/da65/attrtab.h
+++ b/src/da65/attrtab.h
@@ -57,6 +57,7 @@ typedef enum attr_t {
atAddrTab = 0x07,
atRtsTab = 0x08,
atTextTab = 0x09,
+ atSkip = 0x0A, /* Skip code completely */
/* Label flags */
atNoLabel = 0x00, /* No label for this address */
diff --git a/src/da65/infofile.c b/src/da65/infofile.c
index bf756ac0f..f31be347a 100644
--- a/src/da65/infofile.c
+++ b/src/da65/infofile.c
@@ -63,6 +63,18 @@
+static void AddAttr (const char* Name, unsigned* Set, unsigned Attr)
+/* Add an attribute to the set and check that it is not given twice */
+{
+ if (*Set & Attr) {
+ /* Attribute is already in the set */
+ InfoError ("%s given twice", Name);
+ }
+ *Set |= Attr;
+}
+
+
+
static void GlobalSection (void)
/* Parse a global section */
{
@@ -96,7 +108,7 @@ static void GlobalSection (void)
InfoNextTok ();
InfoAssureInt ();
InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS);
- Comments = InfoIVal;
+ Comments = InfoIVal;
InfoNextTok ();
break;
@@ -139,7 +151,7 @@ static void GlobalSection (void)
case INFOTOK_OUTPUTNAME:
InfoNextTok ();
InfoAssureStr ();
- if (OutFile) {
+ if (OutFile) {
InfoError ("Output file name already given");
}
OutFile = xstrdup (InfoSVal);
@@ -147,7 +159,7 @@ static void GlobalSection (void)
break;
case INFOTOK_PAGELENGTH:
- InfoNextTok ();
+ InfoNextTok ();
InfoAssureInt ();
if (InfoIVal != 0) {
InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
@@ -188,14 +200,15 @@ static void RangeSection (void)
};
static const IdentTok TypeDefs[] = {
- { "CODE", INFOTOK_CODE },
- { "BYTETABLE", INFOTOK_BYTETAB },
- { "DBYTETABLE", INFOTOK_DBYTETAB },
- { "WORDTABLE", INFOTOK_WORDTAB },
- { "DWORDTABLE", INFOTOK_DWORDTAB },
{ "ADDRTABLE", INFOTOK_ADDRTAB },
+ { "BYTETABLE", INFOTOK_BYTETAB },
+ { "CODE", INFOTOK_CODE },
+ { "DBYTETABLE", INFOTOK_DBYTETAB },
+ { "DWORDTABLE", INFOTOK_DWORDTAB },
{ "RTSTABLE", INFOTOK_RTSTAB },
+ { "SKIP", INFOTOK_SKIP },
{ "TEXTTABLE", INFOTOK_TEXTTAB },
+ { "WORDTABLE", INFOTOK_WORDTAB },
};
@@ -207,7 +220,8 @@ static void RangeSection (void)
tType = 0x04,
tName = 0x08,
tNeeded = (tStart | tEnd | tType)
- } Attributes = tNone;
+ };
+ unsigned Attributes = tNone;
/* Locals - initialize to avoid gcc warnings */
unsigned Start = 0;
@@ -231,51 +245,50 @@ static void RangeSection (void)
switch (InfoTok) {
case INFOTOK_END:
+ AddAttr ("END", &Attributes, tEnd);
InfoNextTok ();
- InfoAssureInt ();
- InfoRangeCheck (0x0000, 0xFFFF);
- End = InfoIVal;
- Attributes |= tEnd;
+ InfoAssureInt ();
+ InfoRangeCheck (0x0000, 0xFFFF);
+ End = InfoIVal;
InfoNextTok ();
break;
case INFOTOK_NAME:
+ AddAttr ("NAME", &Attributes, tName);
InfoNextTok ();
- if (Name) {
- InfoError ("Name already given");
- }
InfoAssureStr ();
- if (InfoSVal[0] == '\0') {
- InfoError ("Name may not be empty");
- }
+ if (InfoSVal[0] == '\0') {
+ InfoError ("Name may not be empty");
+ }
Name = xstrdup (InfoSVal);
Attributes |= tName;
InfoNextTok ();
break;
case INFOTOK_START:
+ AddAttr ("START", &Attributes, tStart);
InfoNextTok ();
InfoAssureInt ();
InfoRangeCheck (0x0000, 0xFFFF);
Start = InfoIVal;
- Attributes |= tStart;
InfoNextTok ();
break;
case INFOTOK_TYPE:
+ AddAttr ("TYPE", &Attributes, tType);
InfoNextTok ();
- InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type");
+ InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "TYPE");
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_BYTETAB: Type = atByteTab; break;
+ case INFOTOK_CODE: Type = atCode; break;
+ case INFOTOK_DBYTETAB: Type = atDByteTab; break;
+ case INFOTOK_DWORDTAB: Type = atDWordTab; break;
case INFOTOK_RTSTAB: Type = atRtsTab; break;
+ case INFOTOK_SKIP: Type = atSkip; break;
case INFOTOK_TEXTTAB: Type = atTextTab; break;
+ case INFOTOK_WORDTAB: Type = atWordTab; break;
}
- Attributes |= tType;
InfoNextTok ();
break;
}
diff --git a/src/da65/main.c b/src/da65/main.c
index 6fcd58218..94e535cb3 100644
--- a/src/da65/main.c
+++ b/src/da65/main.c
@@ -238,8 +238,13 @@ static void OneOpcode (unsigned RemainingBytes)
/* Get the opcode description for the opcode byte */
const OpcDesc* D = &OpcTable[OPC];
- /* If we have a label at this address, output the label */
- if (MustDefLabel (PC)) {
+ /* 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 (Style != atSkip && MustDefLabel (PC)) {
DefLabel (GetLabel (PC));
}
@@ -249,7 +254,7 @@ static void OneOpcode (unsigned RemainingBytes)
* - ...if there is no label somewhere between the instruction bytes.
* If any of these conditions is false, switch to data mode.
*/
- if (GetStyleAttr (PC) == atDefault) {
+ if (Style == atDefault) {
if (D->Size > RemainingBytes) {
MarkAddr (PC, atIllegal);
} else if (D->Flags & flIllegal) {
@@ -257,16 +262,16 @@ static void OneOpcode (unsigned RemainingBytes)
} else {
unsigned I;
for (I = 1; I < D->Size; ++I) {
- if (HaveLabel (PC+I)) {
- MarkAddr (PC, atIllegal);
- break;
- }
+ if (HaveLabel (PC+I)) {
+ MarkAddr (PC, atIllegal);
+ break;
+ }
}
}
}
/* Disassemble the line */
- switch (GetStyleAttr (PC)) {
+ switch (Style) {
case atDefault:
case atCode:
@@ -293,7 +298,7 @@ static void OneOpcode (unsigned RemainingBytes)
case atAddrTab:
AddrTable ();
break;
-
+
case atRtsTab:
RtsTable ();
break;
@@ -302,6 +307,10 @@ static void OneOpcode (unsigned RemainingBytes)
TextTable ();
break;
+ case atSkip:
+ ++PC;
+ break;
+
default:
DataByteLine (1);
++PC;
diff --git a/src/da65/scanner.h b/src/da65/scanner.h
index 28e24784b..4d6c37872 100644
--- a/src/da65/scanner.h
+++ b/src/da65/scanner.h
@@ -87,6 +87,7 @@ typedef enum token_t {
INFOTOK_ADDRTAB,
INFOTOK_RTSTAB,
INFOTOK_TEXTTAB,
+ INFOTOK_SKIP,
/* Label section */
INFOTOK_NAME,