mirror of
https://github.com/cc65/cc65.git
synced 2025-01-18 11:29:45 +00:00
Teach attrtab, labels and comments about long addresses
This commit is contained in:
parent
67384a29b7
commit
ea924ededd
@ -34,6 +34,7 @@
|
||||
|
||||
|
||||
/* da65 */
|
||||
#include "cpu.h"
|
||||
#include "error.h"
|
||||
#include "attrtab.h"
|
||||
|
||||
@ -48,6 +49,12 @@
|
||||
/* Attribute table */
|
||||
static unsigned short AttrTab[0x10000];
|
||||
|
||||
/* 65816 attribute table */
|
||||
#define MAX_LONG_ATTRS 256
|
||||
static unsigned short LongAttrVal[MAX_LONG_ATTRS];
|
||||
static unsigned LongAttrAddr[MAX_LONG_ATTRS];
|
||||
static unsigned LongAttrsUsed;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -59,12 +66,19 @@ static unsigned short AttrTab[0x10000];
|
||||
void AddrCheck (unsigned Addr)
|
||||
/* Check if the given address has a valid range */
|
||||
{
|
||||
if (Addr >= 0x10000) {
|
||||
if (Addr >= 0x10000 && CPU != CPU_65816) {
|
||||
Error ("Address out of range: %08X", Addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned char IsLongAddr (unsigned Addr)
|
||||
/* Is it 24-bit? */
|
||||
{
|
||||
return Addr >= 0x10000 && CPU == CPU_65816;
|
||||
}
|
||||
|
||||
|
||||
|
||||
attr_t GetAttr (unsigned Addr)
|
||||
/* Return the attribute for the given address */
|
||||
@ -72,6 +86,17 @@ attr_t GetAttr (unsigned Addr)
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
if (IsLongAddr (Addr)) {
|
||||
unsigned i;
|
||||
for (i = 0; i < LongAttrsUsed; i++) {
|
||||
if (LongAttrAddr[i] == Addr) {
|
||||
return LongAttrVal[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the attribute */
|
||||
return AttrTab[Addr];
|
||||
}
|
||||
@ -148,6 +173,33 @@ void MarkAddr (unsigned Addr, attr_t Attr)
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
if (IsLongAddr (Addr)) {
|
||||
unsigned i;
|
||||
for (i = 0; i < LongAttrsUsed; i++) {
|
||||
if (LongAttrAddr[i] == Addr) {
|
||||
|
||||
/* We must not have more than one style bit */
|
||||
if (Attr & atStyleMask) {
|
||||
if (LongAttrVal[i] & atStyleMask) {
|
||||
Error ("Duplicate style for long address %06X", Addr);
|
||||
}
|
||||
}
|
||||
LongAttrVal[i] |= Attr;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (LongAttrsUsed >= MAX_LONG_ATTRS) {
|
||||
Error ("Too many long addresses");
|
||||
}
|
||||
LongAttrVal[LongAttrsUsed] |= Attr;
|
||||
LongAttrAddr[LongAttrsUsed] = Addr;
|
||||
LongAttrsUsed++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* We must not have more than one style bit */
|
||||
if (Attr & atStyleMask) {
|
||||
if (AttrTab[Addr] & atStyleMask) {
|
||||
@ -168,7 +220,7 @@ attr_t GetStyleAttr (unsigned Addr)
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the attribute */
|
||||
return (AttrTab[Addr] & atStyleMask);
|
||||
return (GetAttr (Addr) & atStyleMask);
|
||||
}
|
||||
|
||||
|
||||
@ -180,5 +232,5 @@ attr_t GetLabelAttr (unsigned Addr)
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the attribute */
|
||||
return (AttrTab[Addr] & atLabelMask);
|
||||
return (GetAttr (Addr) & atLabelMask);
|
||||
}
|
||||
|
@ -88,6 +88,9 @@ typedef enum attr_t {
|
||||
void AddrCheck (unsigned Addr);
|
||||
/* Check if the given address has a valid range */
|
||||
|
||||
unsigned char IsLongAddr (unsigned Addr);
|
||||
/* Check if the given address is 24-bit */
|
||||
|
||||
attr_t GetAttr (unsigned Addr);
|
||||
/* Return the attribute for the given address */
|
||||
|
||||
|
@ -52,6 +52,11 @@
|
||||
/* Comment table */
|
||||
static const char* CommentTab[0x10000];
|
||||
|
||||
#define MAX_LONG_COMMENTS 256
|
||||
static const char* LongCommentVal[MAX_LONG_COMMENTS];
|
||||
static unsigned LongCommentAddr[MAX_LONG_COMMENTS];
|
||||
static unsigned LongCommentsUsed;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -60,17 +65,43 @@ static const char* CommentTab[0x10000];
|
||||
|
||||
|
||||
|
||||
static unsigned FindLongIndex (unsigned Addr)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < LongCommentsUsed; i++) {
|
||||
if (LongCommentAddr[i] == Addr) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SetComment (unsigned Addr, const char* Comment)
|
||||
/* Set a comment for the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* If we do already have a comment, warn and ignore the new one */
|
||||
if (CommentTab[Addr]) {
|
||||
Warning ("Duplicate comment for address $%04X", Addr);
|
||||
if (IsLongAddr (Addr)) {
|
||||
if (FindLongIndex (Addr)) {
|
||||
Warning ("Duplicate comment for address $%06X", Addr);
|
||||
} else {
|
||||
if (LongCommentsUsed >= MAX_LONG_COMMENTS) {
|
||||
Error("Too many long-address comments");
|
||||
}
|
||||
LongCommentVal[LongCommentsUsed] = xstrdup (Comment);
|
||||
LongCommentAddr[LongCommentsUsed] = Addr;
|
||||
LongCommentsUsed++;
|
||||
}
|
||||
} else {
|
||||
CommentTab[Addr] = xstrdup (Comment);
|
||||
/* If we do already have a comment, warn and ignore the new one */
|
||||
if (CommentTab[Addr]) {
|
||||
Warning ("Duplicate comment for address $%04X", Addr);
|
||||
} else {
|
||||
CommentTab[Addr] = xstrdup (Comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +113,14 @@ const char* GetComment (unsigned Addr)
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
if (IsLongAddr (Addr)) {
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
if (i < LongCommentsUsed) {
|
||||
return LongCommentVal[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the label if any */
|
||||
return CommentTab[Addr];
|
||||
}
|
||||
|
@ -60,6 +60,12 @@
|
||||
/* Symbol table */
|
||||
static const char* SymTab[0x10000];
|
||||
|
||||
/* 65816 symbol table */
|
||||
#define MAX_LONG_LABELS 256
|
||||
static const char* LongSymVal[MAX_LONG_LABELS];
|
||||
static unsigned LongSymAddr[MAX_LONG_LABELS];
|
||||
static unsigned LongLabelsUsed;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -74,12 +80,27 @@ static const char* MakeLabelName (unsigned Addr)
|
||||
*/
|
||||
{
|
||||
static char LabelBuf [32];
|
||||
xsprintf (LabelBuf, sizeof (LabelBuf), "L%04X", Addr);
|
||||
xsprintf (LabelBuf, sizeof (LabelBuf),
|
||||
IsLongAddr (Addr) ? "L%06X" : "L%04X", Addr);
|
||||
return LabelBuf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned FindLongIndex (unsigned Addr)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < LongLabelsUsed; i++) {
|
||||
if (LongSymAddr[i] == Addr) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
|
||||
/* Add a label */
|
||||
{
|
||||
@ -91,19 +112,41 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
|
||||
/* Allow redefinition if identical. Beware: Unnamed labels don't
|
||||
** have a name (you guessed that, didn't you?).
|
||||
*/
|
||||
if (ExistingAttr == Attr &&
|
||||
((Name == 0 && SymTab[Addr] == 0) ||
|
||||
(Name != 0 && SymTab[Addr] != 0 &&
|
||||
strcmp (SymTab[Addr], Name) == 0))) {
|
||||
return;
|
||||
if (IsLongAddr (Addr)) {
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
if (ExistingAttr == Attr &&
|
||||
((Name == 0 && LongSymVal[i] == 0) ||
|
||||
(Name != 0 && LongSymVal[i] != 0 &&
|
||||
strcmp (LongSymVal[i], Name) == 0))) {
|
||||
return;
|
||||
}
|
||||
Error ("Duplicate label for address $%06X (%s): '%s'", Addr,
|
||||
LongSymVal[i] == 0 ? "<unnamed label>" : LongSymVal[i],
|
||||
Name == 0 ? "<unnamed label>" : Name);
|
||||
} else {
|
||||
if (ExistingAttr == Attr &&
|
||||
((Name == 0 && SymTab[Addr] == 0) ||
|
||||
(Name != 0 && SymTab[Addr] != 0 &&
|
||||
strcmp (SymTab[Addr], Name) == 0))) {
|
||||
return;
|
||||
}
|
||||
Error ("Duplicate label for address $%04X (%s): '%s'", Addr,
|
||||
SymTab[Addr] == 0 ? "<unnamed label>" : SymTab[Addr],
|
||||
Name == 0 ? "<unnamed label>" : Name);
|
||||
}
|
||||
Error ("Duplicate label for address $%04X (%s): '%s'", Addr,
|
||||
SymTab[Addr] == 0 ? "<unnamed label>" : SymTab[Addr],
|
||||
Name == 0 ? "<unnamed label>" : Name);
|
||||
}
|
||||
|
||||
/* Create a new label (xstrdup will return NULL if input NULL) */
|
||||
SymTab[Addr] = xstrdup (Name);
|
||||
if (IsLongAddr (Addr)) {
|
||||
if (LongLabelsUsed >= MAX_LONG_LABELS) {
|
||||
Error ("Too many long labels");
|
||||
}
|
||||
LongSymAddr[LongLabelsUsed] = Addr;
|
||||
LongSymVal[LongLabelsUsed] = xstrdup (Name);
|
||||
LongLabelsUsed++;
|
||||
} else {
|
||||
SymTab[Addr] = xstrdup (Name);
|
||||
}
|
||||
|
||||
/* Remember the attribute */
|
||||
MarkAddr (Addr, Attr);
|
||||
@ -254,6 +297,10 @@ const char* GetLabelName (unsigned Addr)
|
||||
*/
|
||||
if (A == atUnnamedLabel) {
|
||||
return "";
|
||||
} else if (IsLongAddr (Addr)) {
|
||||
/* Return the label if any */
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
return i < LongLabelsUsed ? LongSymVal[i] : NULL;
|
||||
} else {
|
||||
/* Return the label if any */
|
||||
return SymTab[Addr];
|
||||
@ -327,6 +374,10 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom)
|
||||
return FwdLabels[Count-1];
|
||||
}
|
||||
|
||||
} else if (IsLongAddr (Addr)) {
|
||||
/* Return the label if any */
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
return i < LongLabelsUsed ? LongSymVal[i] : NULL;
|
||||
} else {
|
||||
/* Return the label if any */
|
||||
return SymTab[Addr];
|
||||
@ -371,7 +422,13 @@ static void DefOutOfRangeLabel (unsigned long Addr)
|
||||
|
||||
case atIntLabel:
|
||||
case atExtLabel:
|
||||
DefConst (SymTab[Addr], GetComment (Addr), Addr);
|
||||
if (IsLongAddr (Addr)) {
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
DefConst (i < LongLabelsUsed ? LongSymVal[i] : NULL,
|
||||
GetComment (Addr), Addr);
|
||||
} else {
|
||||
DefConst (SymTab[Addr], GetComment (Addr), Addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case atUnnamedLabel:
|
||||
|
Loading…
x
Reference in New Issue
Block a user