<tag><tt>INPUTSIZE</tt></tag>
- INPUTSIZE is followed by a numerical value that gives the amount of data
- to read from the input file. Data beyond <tt/INPUTOFFS+INPUTSIZE/ is
- ignored.
+ <tt/INPUTSIZE/ is followed by a numerical value that gives the amount of
+ data to read from the input file. Data beyond <tt/INPUTOFFS + INPUTSIZE/
+ is ignored.
<tag><tt>OUTPUTNAME</tt></tag>
<tag><tt>TEXTTABLE</tt></tag>
The range consists of readable text.
+
+ <tag><tt>SKIP</tt></tag>
+ The range is simply ignored when generating the output file. Please note
+ that this means that reassembling the output file will <em/not/ generate
+ the original file, not only because the missing piece in between, but also
+ because the following code will located on wrong addresses. Output
+ generated with <tt/SKIP/ ranges will need manual rework.
+
</descrip>
</descrip>
+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 */
{
InfoNextTok ();
InfoAssureInt ();
InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS);
- Comments = InfoIVal;
+ Comments = InfoIVal;
InfoNextTok ();
break;
case INFOTOK_OUTPUTNAME:
InfoNextTok ();
InfoAssureStr ();
- if (OutFile) {
+ if (OutFile) {
InfoError ("Output file name already given");
}
OutFile = xstrdup (InfoSVal);
break;
case INFOTOK_PAGELENGTH:
- InfoNextTok ();
+ InfoNextTok ();
InfoAssureInt ();
if (InfoIVal != 0) {
InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
};
static const IdentTok TypeDefs[] = {
- { "CODE", INFOTOK_CODE },
+ { "ADDRTABLE", INFOTOK_ADDRTAB },
{ "BYTETABLE", INFOTOK_BYTETAB },
+ { "CODE", INFOTOK_CODE },
{ "DBYTETABLE", INFOTOK_DBYTETAB },
- { "WORDTABLE", INFOTOK_WORDTAB },
{ "DWORDTABLE", INFOTOK_DWORDTAB },
- { "ADDRTABLE", INFOTOK_ADDRTAB },
{ "RTSTABLE", INFOTOK_RTSTAB },
+ { "SKIP", INFOTOK_SKIP },
{ "TEXTTABLE", INFOTOK_TEXTTAB },
+ { "WORDTABLE", INFOTOK_WORDTAB },
};
tType = 0x04,
tName = 0x08,
tNeeded = (tStart | tEnd | tType)
- } Attributes = tNone;
+ };
+ unsigned Attributes = tNone;
/* Locals - initialize to avoid gcc warnings */
unsigned Start = 0;
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_ADDRTAB: Type = atAddrTab; break;
case INFOTOK_BYTETAB: Type = atByteTab; break;
+ case INFOTOK_CODE: Type = atCode; 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_SKIP: Type = atSkip; break;
case INFOTOK_TEXTTAB: Type = atTextTab; break;
+ case INFOTOK_WORDTAB: Type = atWordTab; break;
}
- Attributes |= tType;
InfoNextTok ();
break;
}
/* 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));
}
* - ...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) {
} 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:
case atAddrTab:
AddrTable ();
break;
-
+
case atRtsTab:
RtsTable ();
break;
TextTable ();
break;
+ case atSkip:
+ ++PC;
+ break;
+
default:
DataByteLine (1);
++PC;