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