mirror of
https://github.com/cc65/cc65.git
synced 2024-12-25 17:29:50 +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:
parent
fd2fa25f28
commit
1b311d932d
@ -270,9 +270,9 @@ following attributes are recognized:
|
||||
|
||||
<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>
|
||||
@ -363,6 +363,14 @@ following attributes are recognized:
|
||||
|
||||
<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>
|
||||
|
@ -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 ();
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -87,6 +87,7 @@ typedef enum token_t {
|
||||
INFOTOK_ADDRTAB,
|
||||
INFOTOK_RTSTAB,
|
||||
INFOTOK_TEXTTAB,
|
||||
INFOTOK_SKIP,
|
||||
|
||||
/* Label section */
|
||||
INFOTOK_NAME,
|
||||
|
Loading…
Reference in New Issue
Block a user