Added labels, SIEZ attribute for labels, dependent labels etc.

git-svn-id: svn://svn.cc65.org/cc65/trunk@343 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2000-09-29 12:26:34 +00:00
parent c15fb9b50f
commit 97f9682307
11 changed files with 273 additions and 48 deletions

View File

@@ -121,16 +121,16 @@ const char* MakeLabelName (unsigned Addr)
void AddLabel (unsigned Addr, const char* Name) void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
/* Add a label */ /* Add a label */
{ {
/* Check the given address */ /* Get an existing label attribute */
AddrCheck (Addr); attr_t ExistingAttr = GetLabelAttr (Addr);
/* Must not have two symbols for one address */ /* Must not have two symbols for one address */
if (SymTab[Addr] != 0) { if (ExistingAttr != atNoLabel) {
if (strcmp (SymTab[Addr], Name) == 0) { /* Allow redefinition if identical */
/* Allow label if it has the same name */ if (ExistingAttr == Attr && strcmp (SymTab[Addr], Name) == 0) {
return; return;
} }
Error ("Duplicate label for address %04X: %s/%s", Addr, SymTab[Addr], Name); Error ("Duplicate label for address %04X: %s/%s", Addr, SymTab[Addr], Name);
@@ -138,6 +138,9 @@ void AddLabel (unsigned Addr, const char* Name)
/* Create a new label */ /* Create a new label */
SymTab[Addr] = xstrdup (Name); SymTab[Addr] = xstrdup (Name);
/* Remember the attribute */
AttrTab[Addr] |= Attr;
} }
@@ -154,6 +157,20 @@ int HaveLabel (unsigned Addr)
int MustDefLabel (unsigned Addr)
/* Return true if we must define a label for this address, that is, if there
* is a label at this address, and it is an external or internal label.
*/
{
/* Get the label attribute */
attr_t A = GetLabelAttr (Addr);
/* Check for an internal or external label */
return (A == atExtLabel || A == atIntLabel);
}
const char* GetLabel (unsigned Addr) const char* GetLabel (unsigned Addr)
/* Return the label for an address */ /* Return the label for an address */
{ {
@@ -166,7 +183,7 @@ const char* GetLabel (unsigned Addr)
unsigned char GetStyle (unsigned Addr) unsigned char GetStyleAttr (unsigned Addr)
/* Return the style attribute for the given address */ /* Return the style attribute for the given address */
{ {
/* Check the given address */ /* Check the given address */
@@ -178,6 +195,18 @@ unsigned char GetStyle (unsigned Addr)
unsigned char GetLabelAttr (unsigned Addr)
/* Return the label attribute for the given address */
{
/* Check the given address */
AddrCheck (Addr);
/* Return the attribute */
return (AttrTab[Addr] & atLabelMask);
}
static void DefineConst (unsigned Addr) static void DefineConst (unsigned Addr)
/* Define an address constant */ /* Define an address constant */
{ {
@@ -198,14 +227,14 @@ void DefOutOfRangeLabels (void)
/* Low range */ /* Low range */
for (Addr = 0; Addr < CodeStart; ++Addr) { for (Addr = 0; Addr < CodeStart; ++Addr) {
if (SymTab [Addr]) { if (MustDefLabel (Addr)) {
DefineConst (Addr); DefineConst (Addr);
} }
} }
/* High range */ /* High range */
for (Addr = CodeEnd+1; Addr < 0x10000; ++Addr) { for (Addr = CodeEnd+1; Addr < 0x10000; ++Addr) {
if (SymTab [Addr]) { if (MustDefLabel (Addr)) {
DefineConst (Addr); DefineConst (Addr);
} }
} }

View File

@@ -46,6 +46,8 @@
typedef enum attr_t attr_t; typedef enum attr_t attr_t;
enum attr_t { enum attr_t {
/* Styles */
atDefault = 0x00, /* Default style */ atDefault = 0x00, /* Default style */
atCode = 0x01, atCode = 0x01,
atIllegal = 0x02, atIllegal = 0x02,
@@ -55,7 +57,14 @@ enum attr_t {
atAddrTab = 0x06, atAddrTab = 0x06,
atRtsTab = 0x07, atRtsTab = 0x07,
atStyleMask = 0x0F /* Output style */ /* Label flags */
atNoLabel = 0x00, /* No label for this address */
atExtLabel = 0x10, /* External label */
atIntLabel = 0x20, /* Internally generated label */
atDepLabel = 0x30, /* Dependent label (always extern) */
atStyleMask = 0x0F, /* Output style */
atLabelMask = 0x30 /* Label information */
}; };
@@ -77,18 +86,26 @@ const char* MakeLabelName (unsigned Addr);
* static buffer. * static buffer.
*/ */
void AddLabel (unsigned Addr, const char* Name); void AddLabel (unsigned Addr, attr_t Attr, const char* Name);
/* Add a label */ /* Add a label */
int HaveLabel (unsigned Addr); int HaveLabel (unsigned Addr);
/* Check if there is a label for the given address */ /* Check if there is a label for the given address */
const char* GetLabel (unsigned Addr); int MustDefLabel (unsigned Addr);
/* Return the label for an address */ /* Return true if we must define a label for this address, that is, if there
* is a label at this address, and it is an external or internal label.
*/
unsigned char GetStyle (unsigned Addr); const char* GetLabel (unsigned Addr);
/* Return the label for an address or NULL if there is none */
unsigned char GetStyleAttr (unsigned Addr);
/* Return the style attribute for the given address */ /* Return the style attribute for the given address */
unsigned char GetLabelAttr (unsigned Addr);
/* Return the label attribute for the given address */
void DefOutOfRangeLabels (void); void DefOutOfRangeLabels (void);
/* Output any labels that are out of the loaded code range */ /* Output any labels that are out of the loaded code range */

View File

@@ -33,6 +33,7 @@
#include <stdio.h>
#if defined(_MSC_VER) #if defined(_MSC_VER)
/* Microsoft compiler */ /* Microsoft compiler */
# include <io.h> # include <io.h>
@@ -214,12 +215,12 @@ static void RangeSection (void)
/* Did we get all required values? */ /* Did we get all required values? */
if (Needed != tAll) { if (Needed != tAll) {
Error ("Required values missing from this section"); CfgError ("Required values missing from this section");
} }
/* Start must be less than end */ /* Start must be less than end */
if (Start > End) { if (Start > End) {
Error ("Start value must not be greater than end value"); CfgError ("Start value must not be greater than end value");
} }
/* Set the range */ /* Set the range */
@@ -234,12 +235,17 @@ static void RangeSection (void)
static void LabelSection (void) static void LabelSection (void)
/* Parse a label section */ /* Parse a label section */
{ {
static const IdentTok Globals[] = { static const IdentTok LabelDefs[] = {
{ "INPUTNAMEL", CFGTOK_INPUTNAME }, { "NAME", CFGTOK_NAME },
{ "OUTPUTNAME", CFGTOK_OUTPUTNAME }, { "ADDR", CFGTOK_ADDR },
{ "PAGELENGTH", CFGTOK_PAGELENGTH }, { "SIZE", CFGTOK_SIZE },
}; };
/* Locals - initialize to avoid gcc warnings */
char* Name = 0;
long Value = -1;
long Size = -1;
/* Skip the token */ /* Skip the token */
CfgNextTok (); CfgNextTok ();
@@ -249,9 +255,97 @@ static void LabelSection (void)
/* Look for section tokens */ /* Look for section tokens */
while (CfgTok != CFGTOK_RCURLY) { while (CfgTok != CFGTOK_RCURLY) {
/* Convert to special token */
CfgSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label directive");
/* Look at the token */
switch (CfgTok) {
case CFGTOK_NAME:
CfgNextTok ();
if (Name) {
CfgError ("Name already given");
}
CfgAssureStr ();
if (CfgSVal[0] == '\0') {
CfgError ("Name may not be empty");
}
Name = xstrdup (CfgSVal);
CfgNextTok ();
break;
case CFGTOK_ADDR:
CfgNextTok ();
if (Value >= 0) {
CfgError ("Value already given");
}
CfgAssureInt ();
CfgRangeCheck (0, 0xFFFF);
Value = CfgIVal;
CfgNextTok ();
break;
case CFGTOK_SIZE:
CfgNextTok ();
if (Size >= 0) {
CfgError ("Size already given");
}
CfgAssureInt ();
CfgRangeCheck (1, 0x800);
Size = CfgIVal;
CfgNextTok ();
break;
} }
/* Directive is followed by a semicolon */
CfgConsumeSemi ();
}
/* Did we get the necessary data */
if (Name == 0) {
CfgError ("Label name is missing");
}
if (Value < 0) {
CfgError ("Label value is missing");
}
if (Size < 0) {
/* Use default */
Size = 1;
}
if (HaveLabel ((unsigned) Value)) {
CfgError ("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);
}
/* Delete the dynamically allocated memory for Name */
xfree (Name);
/* Consume the closing brace */ /* Consume the closing brace */
CfgConsumeRCurly (); CfgConsumeRCurly ();
} }

View File

@@ -61,7 +61,7 @@ static unsigned GetSpan (attr_t Style)
*/ */
unsigned Count = 1; unsigned Count = 1;
while (Count < RemainingBytes) { while (Count < RemainingBytes) {
if (HaveLabel(PC+Count) || GetStyle (PC+Count) != Style) { if (MustDefLabel(PC+Count) || GetStyleAttr (PC+Count) != Style) {
break; break;
} }
++Count; ++Count;
@@ -81,6 +81,15 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u
/* Count how many bytes may be output. */ /* Count how many bytes may be output. */
unsigned Count = GetSpan (Style); unsigned Count = GetSpan (Style);
/* If the count is less than the member size, print a row of Count data
* bytes. We assume here that there is no member with a size that is less
* than BytesPerLine.
*/
if (Count < MemberSize) {
DataByteLine (Count);
return Count;
}
/* Make Count an even number of multiples of MemberSize */ /* Make Count an even number of multiples of MemberSize */
Count &= ~(MemberSize-1); Count &= ~(MemberSize-1);
@@ -100,7 +109,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u
} }
/* If the next line is not the same style, add a separator */ /* If the next line is not the same style, add a separator */
if (CodeLeft() && GetStyle (PC) != Style) { if (CodeLeft() && GetStyleAttr (PC) != Style) {
SeparatorLine (); SeparatorLine ();
} }
@@ -145,6 +154,8 @@ unsigned AddrTable (void)
/* Count how many bytes may be output. */ /* Count how many bytes may be output. */
unsigned Count = GetSpan (atAddrTab); unsigned Count = GetSpan (atAddrTab);
/* Need to handle Count == 1 here!!! ### */
/* Make the given number even */ /* Make the given number even */
Count &= ~1U; Count &= ~1U;
@@ -160,7 +171,7 @@ unsigned AddrTable (void)
/* In pass 1, define a label, in pass 2 output the line */ /* In pass 1, define a label, in pass 2 output the line */
if (Pass == 1) { if (Pass == 1) {
if (!HaveLabel (Addr)) { if (!HaveLabel (Addr)) {
AddLabel (Addr, MakeLabelName (Addr)); AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
} }
} else { } else {
const char* Label = GetLabel (Addr); const char* Label = GetLabel (Addr);
@@ -182,7 +193,64 @@ unsigned AddrTable (void)
} }
/* If the next line is not a byte table line, add a separator */ /* If the next line is not a byte table line, add a separator */
if (CodeLeft() && GetStyle (PC) != atAddrTab) { if (CodeLeft() && GetStyleAttr (PC) != atAddrTab) {
SeparatorLine ();
}
/* Return the number of bytes output */
return Count;
}
unsigned RtsTable (void)
/* Output a table of RTS addresses (address - 1) */
{
unsigned BytesLeft;
/* Count how many bytes may be output. */
unsigned Count = GetSpan (atRtsTab);
/* Need to handle Count == 1 here!!! ### */
/* Make the given number even */
Count &= ~1U;
/* Output as many data bytes lines as needed. For addresses, each line
* will hold just one address.
*/
BytesLeft = Count;
while (BytesLeft > 0) {
/* Get the address */
unsigned Addr = GetCodeWord (PC) + 1;
/* In pass 1, define a label, in pass 2 output the line */
if (Pass == 1) {
if (!HaveLabel (Addr)) {
AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
}
} else {
const char* Label = GetLabel (Addr);
if (Label == 0) {
/* OOPS! Should not happen */
Internal ("OOPS - Label for address %04X disappeard!", Addr);
}
Indent (MIndent);
Output (".word");
Indent (AIndent);
Output ("%s-1", Label);
LineComment (PC, 2);
LineFeed ();
}
/* Next line */
PC += 2;
BytesLeft -= 2;
}
/* If the next line is not a byte table line, add a separator */
if (CodeLeft() && GetStyleAttr (PC) != atRtsTab) {
SeparatorLine (); SeparatorLine ();
} }

View File

@@ -56,6 +56,9 @@ unsigned DWordTable (void);
unsigned AddrTable (void); unsigned AddrTable (void);
/* Output a table of addresses */ /* Output a table of addresses */
unsigned RtsTable (void);
/* Output a table of RTS addresses (address - 1) */
/* End of data.h */ /* End of data.h */

View File

@@ -118,7 +118,7 @@ static void GenerateLabel (const OpcDesc* D, unsigned Addr)
if (Pass == 1 && !HaveLabel (Addr)) { if (Pass == 1 && !HaveLabel (Addr)) {
if ((D->LabelFlag & lfGenLabel) != 0 || if ((D->LabelFlag & lfGenLabel) != 0 ||
((D->LabelFlag & lfUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd)) { ((D->LabelFlag & lfUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd)) {
AddLabel (Addr, MakeLabelName (Addr)); AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
} }
} }
} }
@@ -397,4 +397,12 @@ void OH_JmpAbsolute (const OpcDesc* D)
void OH_JmpAbsoluteIndirect (const OpcDesc* D)
{
OH_AbsoluteIndirect (D);
SeparatorLine ();
}

View File

@@ -78,6 +78,7 @@ void OH_AbsoluteXIndirect (const OpcDesc*);
/* Handlers for special instructions */ /* Handlers for special instructions */
void OH_Rts (const OpcDesc*); void OH_Rts (const OpcDesc*);
void OH_JmpAbsolute (const OpcDesc*); void OH_JmpAbsolute (const OpcDesc*);
void OH_JmpAbsoluteIndirect (const OpcDesc* D);

View File

@@ -174,9 +174,8 @@ static void OneOpcode (unsigned RemainingBytes)
const OpcDesc* D = &OpcTable[OPC]; const OpcDesc* D = &OpcTable[OPC];
/* If we have a label at this address, output the label */ /* If we have a label at this address, output the label */
const char* Label = GetLabel (PC); if (MustDefLabel (PC)) {
if (Label) { DefLabel (GetLabel (PC));
DefLabel (Label);
} }
/* Check... /* Check...
@@ -185,7 +184,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 true, switch to data mode. * If any of these conditions is true, switch to data mode.
*/ */
if (GetStyle (PC) == atDefault) { if (GetStyleAttr (PC) == atDefault) {
if (D->Size > RemainingBytes) { if (D->Size > RemainingBytes) {
MarkAddr (PC, atIllegal); MarkAddr (PC, atIllegal);
} else if ((D->CPU & CPU) != CPU) { } else if ((D->CPU & CPU) != CPU) {
@@ -202,7 +201,7 @@ static void OneOpcode (unsigned RemainingBytes)
} }
/* Disassemble the line */ /* Disassemble the line */
switch (GetStyle (PC)) { switch (GetStyleAttr (PC)) {
case atDefault: case atDefault:
case atCode: case atCode:
@@ -226,6 +225,10 @@ static void OneOpcode (unsigned RemainingBytes)
AddrTable (); AddrTable ();
break; break;
case atRtsTab:
RtsTable ();
break;
default: default:
DataByteLine (1); DataByteLine (1);
++PC; ++PC;

View File

@@ -500,7 +500,7 @@ const OpcDesc OpcTable[256] = {
1, 1,
0, 0,
CPU_ALL, CPU_ALL,
OH_Implicit OH_Rts
}, },
{ /* $41 */ { /* $41 */
"eor", "eor",
@@ -808,7 +808,7 @@ const OpcDesc OpcTable[256] = {
3, 3,
lfLabel, lfLabel,
CPU_ALL, CPU_ALL,
OH_AbsoluteIndirect OH_JmpAbsoluteIndirect
}, },
{ /* $6d */ { /* $6d */
"adc", "adc",

View File

@@ -158,7 +158,7 @@ void DefLabel (const char* Name)
{ {
Output ("%s:", Name); Output ("%s:", Name);
/* Don't start a new line if the label is fully in the left column */ /* Don't start a new line if the label is fully in the left column */
if (Col >= MIndent-1) { if (Col > MIndent) {
LineFeed (); LineFeed ();
} }
} }

View File

@@ -82,7 +82,9 @@ typedef enum token_t {
CFGTOK_RTSTAB, CFGTOK_RTSTAB,
/* Label section */ /* Label section */
CFGTOK_NAME,
CFGTOK_ADDR,
CFGTOK_SIZE,
/* */ /* */
CFGTOK_TRUE, CFGTOK_TRUE,