Teach attrtab, labels and comments about long addresses

This commit is contained in:
Lauri Kasanen 2022-10-12 11:41:20 +03:00
parent 67384a29b7
commit ea924ededd
4 changed files with 169 additions and 18 deletions

View File

@ -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);
}

View File

@ -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 */

View File

@ -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];
}

View File

@ -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: