1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 00:29:31 +00:00

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 */
{
/* Check the given address */
AddrCheck (Addr);
/* Get an existing label attribute */
attr_t ExistingAttr = GetLabelAttr (Addr);
/* Must not have two symbols for one address */
if (SymTab[Addr] != 0) {
if (strcmp (SymTab[Addr], Name) == 0) {
/* Allow label if it has the same name */
if (ExistingAttr != atNoLabel) {
/* Allow redefinition if identical */
if (ExistingAttr == Attr && strcmp (SymTab[Addr], Name) == 0) {
return;
}
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 */
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)
/* 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 */
{
/* 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)
/* Define an address constant */
{
@ -198,14 +227,14 @@ void DefOutOfRangeLabels (void)
/* Low range */
for (Addr = 0; Addr < CodeStart; ++Addr) {
if (SymTab [Addr]) {
if (MustDefLabel (Addr)) {
DefineConst (Addr);
}
}
/* High range */
for (Addr = CodeEnd+1; Addr < 0x10000; ++Addr) {
if (SymTab [Addr]) {
if (MustDefLabel (Addr)) {
DefineConst (Addr);
}
}

View File

@ -39,13 +39,15 @@
/*****************************************************************************/
/* Data */
/* Data */
/*****************************************************************************/
typedef enum attr_t attr_t;
enum attr_t {
/* Styles */
atDefault = 0x00, /* Default style */
atCode = 0x01,
atIllegal = 0x02,
@ -55,13 +57,20 @@ enum attr_t {
atAddrTab = 0x06,
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 */
};
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
@ -77,18 +86,26 @@ const char* MakeLabelName (unsigned Addr);
* static buffer.
*/
void AddLabel (unsigned Addr, const char* Name);
void AddLabel (unsigned Addr, attr_t Attr, const char* Name);
/* Add a label */
int HaveLabel (unsigned Addr);
/* Check if there is a label for the given address */
const char* GetLabel (unsigned Addr);
/* Return the label for an address */
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.
*/
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 */
unsigned char GetLabelAttr (unsigned Addr);
/* Return the label attribute for the given address */
void DefOutOfRangeLabels (void);
/* Output any labels that are out of the loaded code range */

View File

@ -33,6 +33,7 @@
#include <stdio.h>
#if defined(_MSC_VER)
/* Microsoft compiler */
# include <io.h>
@ -200,7 +201,7 @@ static void RangeSection (void)
case CFGTOK_WORDTAB: Type = atWordTab; break;
case CFGTOK_DWORDTAB: Type = atDWordTab; break;
case CFGTOK_ADDRTAB: Type = atAddrTab; break;
case CFGTOK_RTSTAB: Type = atRtsTab; break;
case CFGTOK_RTSTAB: Type = atRtsTab; break;
}
Needed |= tType;
CfgNextTok ();
@ -214,12 +215,12 @@ static void RangeSection (void)
/* Did we get all required values? */
if (Needed != tAll) {
Error ("Required values missing from this section");
CfgError ("Required values missing from this section");
}
/* Start must be less than 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 */
@ -234,12 +235,17 @@ static void RangeSection (void)
static void LabelSection (void)
/* Parse a label section */
{
static const IdentTok Globals[] = {
{ "INPUTNAMEL", CFGTOK_INPUTNAME },
{ "OUTPUTNAME", CFGTOK_OUTPUTNAME },
{ "PAGELENGTH", CFGTOK_PAGELENGTH },
static const IdentTok LabelDefs[] = {
{ "NAME", CFGTOK_NAME },
{ "ADDR", CFGTOK_ADDR },
{ "SIZE", CFGTOK_SIZE },
};
/* Locals - initialize to avoid gcc warnings */
char* Name = 0;
long Value = -1;
long Size = -1;
/* Skip the token */
CfgNextTok ();
@ -249,9 +255,97 @@ static void LabelSection (void)
/* Look for section tokens */
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 */
CfgConsumeRCurly ();
}
@ -262,8 +356,8 @@ static void CfgParse (void)
/* Parse the config file */
{
static const IdentTok Globals[] = {
{ "GLOBAL", CFGTOK_GLOBAL },
{ "RANGE", CFGTOK_RANGE },
{ "GLOBAL", CFGTOK_GLOBAL },
{ "RANGE", CFGTOK_RANGE },
{ "LABEL", CFGTOK_LABEL },
};

View File

@ -61,7 +61,7 @@ static unsigned GetSpan (attr_t Style)
*/
unsigned Count = 1;
while (Count < RemainingBytes) {
if (HaveLabel(PC+Count) || GetStyle (PC+Count) != Style) {
if (MustDefLabel(PC+Count) || GetStyleAttr (PC+Count) != Style) {
break;
}
++Count;
@ -81,6 +81,15 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u
/* Count how many bytes may be output. */
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 */
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 (CodeLeft() && GetStyle (PC) != Style) {
if (CodeLeft() && GetStyleAttr (PC) != Style) {
SeparatorLine ();
}
@ -145,12 +154,14 @@ unsigned AddrTable (void)
/* Count how many bytes may be output. */
unsigned Count = GetSpan (atAddrTab);
/* 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) {
@ -160,7 +171,7 @@ unsigned AddrTable (void)
/* In pass 1, define a label, in pass 2 output the line */
if (Pass == 1) {
if (!HaveLabel (Addr)) {
AddLabel (Addr, MakeLabelName (Addr));
AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
}
} else {
const char* Label = GetLabel (Addr);
@ -182,9 +193,66 @@ unsigned AddrTable (void)
}
/* 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 ();
}
/* Return the number of bytes output */
return Count;

View File

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

View File

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

View File

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

View File

@ -146,8 +146,8 @@ void LineFeed (void)
++Page;
PageHeader ();
Line = 4;
}
Col = 1;
}
Col = 1;
}
}
@ -158,7 +158,7 @@ void DefLabel (const char* Name)
{
Output ("%s:", Name);
/* Don't start a new line if the label is fully in the left column */
if (Col >= MIndent-1) {
if (Col > MIndent) {
LineFeed ();
}
}
@ -174,11 +174,11 @@ void DataByteLine (unsigned ByteCount)
Output (".byte");
Indent (AIndent);
for (I = 0; I < ByteCount; ++I) {
if (I > 0) {
Output (",$%02X", CodeBuf[PC+I]);
} else {
Output ("$%02X", CodeBuf[PC+I]);
}
if (I > 0) {
Output (",$%02X", CodeBuf[PC+I]);
} else {
Output ("$%02X", CodeBuf[PC+I]);
}
}
LineComment (PC, ByteCount);
LineFeed ();

View File

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