1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-26 08:32:00 +00:00

Add new SKIP range

git-svn-id: svn://svn.cc65.org/cc65/trunk@2412 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-08-23 21:19:20 +00:00
parent fd2fa25f28
commit 1b311d932d
6 changed files with 84 additions and 41 deletions

View File

@ -270,9 +270,9 @@ following attributes are recognized:
<tag><tt>INPUTSIZE</tt></tag> <tag><tt>INPUTSIZE</tt></tag>
INPUTSIZE is followed by a numerical value that gives the amount of data <tt/INPUTSIZE/ is followed by a numerical value that gives the amount of
to read from the input file. Data beyond <tt/INPUTOFFS+INPUTSIZE/ is data to read from the input file. Data beyond <tt/INPUTOFFS + INPUTSIZE/
ignored. is ignored.
<tag><tt>OUTPUTNAME</tt></tag> <tag><tt>OUTPUTNAME</tt></tag>
@ -363,6 +363,14 @@ following attributes are recognized:
<tag><tt>TEXTTABLE</tt></tag> <tag><tt>TEXTTABLE</tt></tag>
The range consists of readable text. 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>
</descrip> </descrip>

View File

@ -260,17 +260,28 @@ void DefOutOfRangeLabels (void)
SeparatorLine (); SeparatorLine ();
/* Low range */ /* Low range */
for (Addr = 0; Addr < CodeStart; ++Addr) { Addr = 0;
while (Addr < CodeStart) {
if (MustDefLabel (Addr)) { if (MustDefLabel (Addr)) {
DefineConst (Addr); DefineConst (Addr);
} }
++Addr;
}
/* Skip areas in code range */
while (Addr <= CodeEnd) {
if ((AttrTab[Addr] & atStyleMask) == atSkip && MustDefLabel (Addr)) {
DefineConst (Addr);
}
++Addr;
} }
/* High range */ /* High range */
for (Addr = CodeEnd+1; Addr < 0x10000; ++Addr) { while (Addr < 0x10000) {
if (MustDefLabel (Addr)) { if (MustDefLabel (Addr)) {
DefineConst (Addr); DefineConst (Addr);
} }
++Addr;
} }
SeparatorLine (); SeparatorLine ();

View File

@ -57,6 +57,7 @@ typedef enum attr_t {
atAddrTab = 0x07, atAddrTab = 0x07,
atRtsTab = 0x08, atRtsTab = 0x08,
atTextTab = 0x09, atTextTab = 0x09,
atSkip = 0x0A, /* Skip code completely */
/* Label flags */ /* Label flags */
atNoLabel = 0x00, /* No label for this address */ atNoLabel = 0x00, /* No label for this address */

View File

@ -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) static void GlobalSection (void)
/* Parse a global section */ /* Parse a global section */
{ {
@ -96,7 +108,7 @@ static void GlobalSection (void)
InfoNextTok (); InfoNextTok ();
InfoAssureInt (); InfoAssureInt ();
InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS); InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS);
Comments = InfoIVal; Comments = InfoIVal;
InfoNextTok (); InfoNextTok ();
break; break;
@ -139,7 +151,7 @@ static void GlobalSection (void)
case INFOTOK_OUTPUTNAME: case INFOTOK_OUTPUTNAME:
InfoNextTok (); InfoNextTok ();
InfoAssureStr (); InfoAssureStr ();
if (OutFile) { if (OutFile) {
InfoError ("Output file name already given"); InfoError ("Output file name already given");
} }
OutFile = xstrdup (InfoSVal); OutFile = xstrdup (InfoSVal);
@ -147,7 +159,7 @@ static void GlobalSection (void)
break; break;
case INFOTOK_PAGELENGTH: case INFOTOK_PAGELENGTH:
InfoNextTok (); InfoNextTok ();
InfoAssureInt (); InfoAssureInt ();
if (InfoIVal != 0) { if (InfoIVal != 0) {
InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN); InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
@ -188,14 +200,15 @@ static void RangeSection (void)
}; };
static const IdentTok TypeDefs[] = { static const IdentTok TypeDefs[] = {
{ "CODE", INFOTOK_CODE },
{ "BYTETABLE", INFOTOK_BYTETAB },
{ "DBYTETABLE", INFOTOK_DBYTETAB },
{ "WORDTABLE", INFOTOK_WORDTAB },
{ "DWORDTABLE", INFOTOK_DWORDTAB },
{ "ADDRTABLE", INFOTOK_ADDRTAB }, { "ADDRTABLE", INFOTOK_ADDRTAB },
{ "BYTETABLE", INFOTOK_BYTETAB },
{ "CODE", INFOTOK_CODE },
{ "DBYTETABLE", INFOTOK_DBYTETAB },
{ "DWORDTABLE", INFOTOK_DWORDTAB },
{ "RTSTABLE", INFOTOK_RTSTAB }, { "RTSTABLE", INFOTOK_RTSTAB },
{ "SKIP", INFOTOK_SKIP },
{ "TEXTTABLE", INFOTOK_TEXTTAB }, { "TEXTTABLE", INFOTOK_TEXTTAB },
{ "WORDTABLE", INFOTOK_WORDTAB },
}; };
@ -207,7 +220,8 @@ static void RangeSection (void)
tType = 0x04, tType = 0x04,
tName = 0x08, tName = 0x08,
tNeeded = (tStart | tEnd | tType) tNeeded = (tStart | tEnd | tType)
} Attributes = tNone; };
unsigned Attributes = tNone;
/* Locals - initialize to avoid gcc warnings */ /* Locals - initialize to avoid gcc warnings */
unsigned Start = 0; unsigned Start = 0;
@ -231,51 +245,50 @@ static void RangeSection (void)
switch (InfoTok) { switch (InfoTok) {
case INFOTOK_END: case INFOTOK_END:
AddAttr ("END", &Attributes, tEnd);
InfoNextTok (); InfoNextTok ();
InfoAssureInt (); InfoAssureInt ();
InfoRangeCheck (0x0000, 0xFFFF); InfoRangeCheck (0x0000, 0xFFFF);
End = InfoIVal; End = InfoIVal;
Attributes |= tEnd;
InfoNextTok (); InfoNextTok ();
break; break;
case INFOTOK_NAME: case INFOTOK_NAME:
AddAttr ("NAME", &Attributes, tName);
InfoNextTok (); InfoNextTok ();
if (Name) {
InfoError ("Name already given");
}
InfoAssureStr (); InfoAssureStr ();
if (InfoSVal[0] == '\0') { if (InfoSVal[0] == '\0') {
InfoError ("Name may not be empty"); InfoError ("Name may not be empty");
} }
Name = xstrdup (InfoSVal); Name = xstrdup (InfoSVal);
Attributes |= tName; Attributes |= tName;
InfoNextTok (); InfoNextTok ();
break; break;
case INFOTOK_START: case INFOTOK_START:
AddAttr ("START", &Attributes, tStart);
InfoNextTok (); InfoNextTok ();
InfoAssureInt (); InfoAssureInt ();
InfoRangeCheck (0x0000, 0xFFFF); InfoRangeCheck (0x0000, 0xFFFF);
Start = InfoIVal; Start = InfoIVal;
Attributes |= tStart;
InfoNextTok (); InfoNextTok ();
break; break;
case INFOTOK_TYPE: case INFOTOK_TYPE:
AddAttr ("TYPE", &Attributes, tType);
InfoNextTok (); InfoNextTok ();
InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type"); InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "TYPE");
switch (InfoTok) { 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_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_RTSTAB: Type = atRtsTab; break;
case INFOTOK_SKIP: Type = atSkip; break;
case INFOTOK_TEXTTAB: Type = atTextTab; break; case INFOTOK_TEXTTAB: Type = atTextTab; break;
case INFOTOK_WORDTAB: Type = atWordTab; break;
} }
Attributes |= tType;
InfoNextTok (); InfoNextTok ();
break; break;
} }

View File

@ -238,8 +238,13 @@ static void OneOpcode (unsigned RemainingBytes)
/* Get the opcode description for the opcode byte */ /* Get the opcode description for the opcode byte */
const OpcDesc* D = &OpcTable[OPC]; const OpcDesc* D = &OpcTable[OPC];
/* If we have a label at this address, output the label */ /* Get the output style for the current PC */
if (MustDefLabel (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)); DefLabel (GetLabel (PC));
} }
@ -249,7 +254,7 @@ static void OneOpcode (unsigned RemainingBytes)
* - ...if there is no label somewhere between the instruction bytes. * - ...if there is no label somewhere between the instruction bytes.
* If any of these conditions is false, switch to data mode. * If any of these conditions is false, switch to data mode.
*/ */
if (GetStyleAttr (PC) == atDefault) { if (Style == atDefault) {
if (D->Size > RemainingBytes) { if (D->Size > RemainingBytes) {
MarkAddr (PC, atIllegal); MarkAddr (PC, atIllegal);
} else if (D->Flags & flIllegal) { } else if (D->Flags & flIllegal) {
@ -257,16 +262,16 @@ static void OneOpcode (unsigned RemainingBytes)
} else { } else {
unsigned I; unsigned I;
for (I = 1; I < D->Size; ++I) { for (I = 1; I < D->Size; ++I) {
if (HaveLabel (PC+I)) { if (HaveLabel (PC+I)) {
MarkAddr (PC, atIllegal); MarkAddr (PC, atIllegal);
break; break;
} }
} }
} }
} }
/* Disassemble the line */ /* Disassemble the line */
switch (GetStyleAttr (PC)) { switch (Style) {
case atDefault: case atDefault:
case atCode: case atCode:
@ -293,7 +298,7 @@ static void OneOpcode (unsigned RemainingBytes)
case atAddrTab: case atAddrTab:
AddrTable (); AddrTable ();
break; break;
case atRtsTab: case atRtsTab:
RtsTable (); RtsTable ();
break; break;
@ -302,6 +307,10 @@ static void OneOpcode (unsigned RemainingBytes)
TextTable (); TextTable ();
break; break;
case atSkip:
++PC;
break;
default: default:
DataByteLine (1); DataByteLine (1);
++PC; ++PC;

View File

@ -87,6 +87,7 @@ typedef enum token_t {
INFOTOK_ADDRTAB, INFOTOK_ADDRTAB,
INFOTOK_RTSTAB, INFOTOK_RTSTAB,
INFOTOK_TEXTTAB, INFOTOK_TEXTTAB,
INFOTOK_SKIP,
/* Label section */ /* Label section */
INFOTOK_NAME, INFOTOK_NAME,