mirror of
https://github.com/cc65/cc65.git
synced 2025-04-11 09:37:10 +00:00
Restructured some of the code. Attribute handling is still a mess and needs
another cleanup. Added unnamed labels. git-svn-id: svn://svn.cc65.org/cc65/trunk@3700 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
7086da868b
commit
d31f72d057
@ -42,8 +42,9 @@
|
||||
|
||||
/* da65 */
|
||||
#include "asminc.h"
|
||||
#include "attrtab.h"
|
||||
#include "comments.h"
|
||||
#include "error.h"
|
||||
#include "labels.h"
|
||||
|
||||
|
||||
|
||||
@ -220,8 +221,9 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown)
|
||||
/* Apply the sign */
|
||||
Val *= Sign;
|
||||
|
||||
/* Define the symbol */
|
||||
AddExtLabel (Val, SB_GetConstBuf (&Ident), Comment);
|
||||
/* Define the symbol and the comment */
|
||||
AddExtLabel (Val, SB_GetConstBuf (&Ident));
|
||||
SetComment (Val, Comment);
|
||||
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2005 Ullrich von Bassewitz */
|
||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||
/* Römerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -33,75 +33,20 @@
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "xmalloc.h"
|
||||
#include "xsprintf.h"
|
||||
|
||||
/* da65 */
|
||||
#include "code.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "output.h"
|
||||
#include "attrtab.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Label + comment */
|
||||
typedef struct {
|
||||
const char* Name;
|
||||
const char* Comment;
|
||||
} Label;
|
||||
|
||||
/* A whole lot of Labels, so we don't have to allocate them separately */
|
||||
static Label* LabelHeap = 0;
|
||||
static unsigned LabelsLeft = 0;
|
||||
|
||||
/* Attribute table */
|
||||
static unsigned char AttrTab [0x10000];
|
||||
|
||||
/* Symbol table */
|
||||
static const Label* SymTab [0x10000];
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* struct Label */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
Label* NewLabel (const char* Name, const char* Comment)
|
||||
/* Create a new Label structure, initialize and return it */
|
||||
{
|
||||
Label* L;
|
||||
|
||||
/* Check if we have some free labels left */
|
||||
if (LabelsLeft == 0) {
|
||||
/* Allocate a new block of memory */
|
||||
LabelsLeft = 200;
|
||||
LabelHeap = xmalloc (LabelsLeft * sizeof (Label));
|
||||
}
|
||||
|
||||
/* Get a new one from the buffer */
|
||||
L = LabelHeap++;
|
||||
--LabelsLeft;
|
||||
|
||||
/* Initialize the new label */
|
||||
L->Name = xstrdup (Name);
|
||||
L->Comment = Comment? xstrdup (Comment) : 0;
|
||||
|
||||
/* Return the new label */
|
||||
return L;
|
||||
}
|
||||
static unsigned short AttrTab[0x10000];
|
||||
|
||||
|
||||
|
||||
@ -111,7 +56,7 @@ Label* NewLabel (const char* Name, const char* Comment)
|
||||
|
||||
|
||||
|
||||
static void AddrCheck (unsigned Addr)
|
||||
void AddrCheck (unsigned Addr)
|
||||
/* Check if the given address has a valid range */
|
||||
{
|
||||
if (Addr >= 0x10000) {
|
||||
@ -175,195 +120,7 @@ void MarkAddr (unsigned Addr, attr_t Attr)
|
||||
|
||||
|
||||
|
||||
static const char* MakeLabelName (unsigned Addr)
|
||||
/* Make the default label name from the given address and return it in a
|
||||
* static buffer.
|
||||
*/
|
||||
{
|
||||
static char LabelBuf [32];
|
||||
xsprintf (LabelBuf, sizeof (LabelBuf), "L%04X", Addr);
|
||||
return LabelBuf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddLabel (unsigned Addr, attr_t Attr, const char* Name, const char* Comment)
|
||||
/* Add a label */
|
||||
{
|
||||
/* Get an existing label attribute */
|
||||
attr_t ExistingAttr = GetLabelAttr (Addr);
|
||||
|
||||
/* Must not have two symbols for one address */
|
||||
if (ExistingAttr != atNoLabel) {
|
||||
/* Allow redefinition if identical */
|
||||
if (ExistingAttr == Attr && strcmp (SymTab[Addr]->Name, Name) == 0) {
|
||||
return;
|
||||
}
|
||||
Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr]->Name, Name);
|
||||
}
|
||||
|
||||
/* Create a new label */
|
||||
SymTab[Addr] = NewLabel (Name, Comment);
|
||||
|
||||
/* Remember the attribute */
|
||||
AttrTab[Addr] |= Attr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddIntLabel (unsigned Addr)
|
||||
/* Add an internal label using the address to generate the name. */
|
||||
{
|
||||
AddLabel (Addr, atIntLabel, MakeLabelName (Addr), 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddExtLabel (unsigned Addr, const char* Name, const char* Comment)
|
||||
/* Add an external label */
|
||||
{
|
||||
AddLabel (Addr, atExtLabel, Name, Comment);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs)
|
||||
/* Add a dependent label at the given address using "base name+Offs" as the new
|
||||
* name.
|
||||
*/
|
||||
{
|
||||
/* Allocate memory for the dependent label name */
|
||||
unsigned NameLen = strlen (BaseName);
|
||||
char* DepName = xmalloc (NameLen + 7); /* "+$ABCD" */
|
||||
|
||||
/* Create the new name in the buffer */
|
||||
if (UseHexOffs) {
|
||||
sprintf (DepName, "%s+$%02X", BaseName, Offs);
|
||||
} else {
|
||||
sprintf (DepName, "%s+%u", BaseName, Offs);
|
||||
}
|
||||
|
||||
/* Define the labels */
|
||||
AddLabel (Addr, Attr | atDepLabel, DepName, 0);
|
||||
|
||||
/* Free the name buffer */
|
||||
xfree (DepName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void AddLabelRange (unsigned Addr, attr_t Attr,
|
||||
const char* Name, const char* Comment,
|
||||
unsigned Count)
|
||||
/* Add a label for a range. The first entry gets the label "Name" while the
|
||||
* others get "Name+offs".
|
||||
*/
|
||||
{
|
||||
/* Define the label */
|
||||
AddLabel (Addr, Attr, Name, Comment);
|
||||
|
||||
/* Define dependent labels if necessary */
|
||||
if (Count > 1) {
|
||||
unsigned Offs;
|
||||
|
||||
/* Setup the format string */
|
||||
const char* Format = UseHexOffs? "$%02X" : "%u";
|
||||
|
||||
/* Allocate memory for the dependent label names */
|
||||
unsigned NameLen = strlen (Name);
|
||||
char* DepName = xmalloc (NameLen + 7); /* "+$ABCD" */
|
||||
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 < Count; ++Offs) {
|
||||
sprintf (DepOffs, Format, Offs);
|
||||
AddLabel (Addr + Offs, Attr | atDepLabel, DepName, 0);
|
||||
}
|
||||
|
||||
/* Free the name buffer */
|
||||
xfree (DepName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count)
|
||||
/* Add an internal label for a range. The first entry gets the label "Name"
|
||||
* while the others get "Name+offs".
|
||||
*/
|
||||
{
|
||||
/* Define the label range */
|
||||
AddLabelRange (Addr, atIntLabel, Name, 0, Count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddExtLabelRange (unsigned Addr, const char* Name, const char* Comment, unsigned Count)
|
||||
/* Add an external label for a range. The first entry gets the label "Name"
|
||||
* while the others get "Name+offs".
|
||||
*/
|
||||
{
|
||||
/* Define the label range */
|
||||
AddLabelRange (Addr, atExtLabel, Name, Comment, Count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int HaveLabel (unsigned Addr)
|
||||
/* Check if there is a label for the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Check for a label */
|
||||
return (SymTab[Addr] != 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the label if any */
|
||||
return SymTab[Addr]? SymTab[Addr]->Name : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* GetComment (unsigned Addr)
|
||||
/* Return the comment for an address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the label if any */
|
||||
return SymTab[Addr]? SymTab[Addr]->Comment : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char GetStyleAttr (unsigned Addr)
|
||||
attr_t GetStyleAttr (unsigned Addr)
|
||||
/* Return the style attribute for the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
@ -375,7 +132,7 @@ unsigned char GetStyleAttr (unsigned Addr)
|
||||
|
||||
|
||||
|
||||
unsigned char GetLabelAttr (unsigned Addr)
|
||||
attr_t GetLabelAttr (unsigned Addr)
|
||||
/* Return the label attribute for the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
@ -387,40 +144,3 @@ unsigned char GetLabelAttr (unsigned Addr)
|
||||
|
||||
|
||||
|
||||
void DefOutOfRangeLabels (void)
|
||||
/* Output any labels that are out of the loaded code range */
|
||||
{
|
||||
unsigned long Addr;
|
||||
|
||||
SeparatorLine ();
|
||||
|
||||
/* Low range */
|
||||
Addr = 0;
|
||||
while (Addr < CodeStart) {
|
||||
if (MustDefLabel (Addr)) {
|
||||
DefineConst (SymTab[Addr]->Name, SymTab[Addr]->Comment, Addr);
|
||||
}
|
||||
++Addr;
|
||||
}
|
||||
|
||||
/* Skip areas in code range */
|
||||
while (Addr <= CodeEnd) {
|
||||
if ((AttrTab[Addr] & atStyleMask) == atSkip && MustDefLabel (Addr)) {
|
||||
DefineConst (SymTab[Addr]->Name, SymTab[Addr]->Comment, Addr);
|
||||
}
|
||||
++Addr;
|
||||
}
|
||||
|
||||
/* High range */
|
||||
while (Addr < 0x10000) {
|
||||
if (MustDefLabel (Addr)) {
|
||||
DefineConst (SymTab[Addr]->Name, SymTab[Addr]->Comment, Addr);
|
||||
}
|
||||
++Addr;
|
||||
}
|
||||
|
||||
SeparatorLine ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* attrtab.h */
|
||||
/* attrtab.h */
|
||||
/* */
|
||||
/* Disassembler attribute table */
|
||||
/* Disassembler attribute table */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2005 Ullrich von Bassewitz */
|
||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||
/* Römerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@ -47,36 +47,42 @@
|
||||
typedef enum attr_t {
|
||||
|
||||
/* Styles */
|
||||
atDefault = 0x00, /* Default style */
|
||||
atCode = 0x01,
|
||||
atIllegal = 0x02,
|
||||
atByteTab = 0x03, /* Same as illegal */
|
||||
atDByteTab = 0x04,
|
||||
atWordTab = 0x05,
|
||||
atDWordTab = 0x06,
|
||||
atAddrTab = 0x07,
|
||||
atRtsTab = 0x08,
|
||||
atTextTab = 0x09,
|
||||
atSkip = 0x0A, /* Skip code completely */
|
||||
atDefault = 0x0000, /* Default style */
|
||||
atCode = 0x0001,
|
||||
atIllegal = 0x0002,
|
||||
atByteTab = 0x0003, /* Same as illegal */
|
||||
atDByteTab = 0x0004,
|
||||
atWordTab = 0x0005,
|
||||
atDWordTab = 0x0006,
|
||||
atAddrTab = 0x0007,
|
||||
atRtsTab = 0x0008,
|
||||
atTextTab = 0x0009,
|
||||
atSkip = 0x000A, /* Skip code completely */
|
||||
|
||||
/* Label flags */
|
||||
atNoLabel = 0x00, /* No label for this address */
|
||||
atExtLabel = 0x10, /* External label */
|
||||
atIntLabel = 0x20, /* Internally generated label */
|
||||
atDepLabel = 0x40, /* Dependent label */
|
||||
atNoLabel = 0x0000, /* No label for this address */
|
||||
atExtLabel = 0x0010, /* External label */
|
||||
atIntLabel = 0x0020, /* Internally generated label */
|
||||
atDepLabel = 0x0040, /* Dependent label */
|
||||
atUnnamedLabel = 0x0080, /* Unnamed label */
|
||||
|
||||
atStyleMask = 0x0F, /* Output style */
|
||||
atLabelMask = 0x70 /* Label information */
|
||||
atLabelDefined = 0x0100, /* True if we defined the label */
|
||||
|
||||
atStyleMask = 0x000F, /* Output style */
|
||||
atLabelMask = 0x00F0 /* Label information */
|
||||
} attr_t;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void AddrCheck (unsigned Addr);
|
||||
/* Check if the given address has a valid range */
|
||||
|
||||
unsigned GetGranularity (attr_t Style);
|
||||
/* Get the granularity for the given style */
|
||||
|
||||
@ -86,53 +92,12 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr);
|
||||
void MarkAddr (unsigned Addr, attr_t Attr);
|
||||
/* Mark an address with an attribute */
|
||||
|
||||
void AddLabel (unsigned Addr, attr_t Attr, const char* Name, const char* Comment);
|
||||
/* Add a label */
|
||||
|
||||
void AddIntLabel (unsigned Addr);
|
||||
/* Add an internal label using the address to generate the name. */
|
||||
|
||||
void AddExtLabel (unsigned Addr, const char* Name, const char* Comment);
|
||||
/* Add an external label */
|
||||
|
||||
void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs);
|
||||
/* Add a dependent label at the given address using "base name+Offs" as the new
|
||||
* name.
|
||||
*/
|
||||
|
||||
void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count);
|
||||
/* Add an internal label for a range. The first entry gets the label "Name"
|
||||
* while the others get "Name+offs".
|
||||
*/
|
||||
|
||||
void AddExtLabelRange (unsigned Addr, const char* Name, const char* Comment, unsigned Count);
|
||||
/* Add an external label for a range. The first entry gets the label "Name"
|
||||
* while the others get "Name+offs".
|
||||
*/
|
||||
|
||||
int HaveLabel (unsigned Addr);
|
||||
/* Check if there is a label for the given 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.
|
||||
*/
|
||||
|
||||
const char* GetLabel (unsigned Addr);
|
||||
/* Return the label for an address or NULL if there is none */
|
||||
|
||||
const char* GetComment (unsigned Addr);
|
||||
/* Return the comment for an address */
|
||||
|
||||
unsigned char GetStyleAttr (unsigned Addr);
|
||||
attr_t GetStyleAttr (unsigned Addr);
|
||||
/* Return the style attribute for the given address */
|
||||
|
||||
unsigned char GetLabelAttr (unsigned Addr);
|
||||
attr_t 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 */
|
||||
|
||||
|
||||
|
||||
/* End of attrtab.h */
|
||||
|
90
src/da65/comments.c
Normal file
90
src/da65/comments.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* comments.c */
|
||||
/* */
|
||||
/* Comment management for da65 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2006 Ullrich von Bassewitz */
|
||||
/* Römerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* common */
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* da65 */
|
||||
#include "attrtab.h"
|
||||
#include "comments.h"
|
||||
#include "error.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Comment table */
|
||||
static const char* CommentTab[0x10000];
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
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);
|
||||
} else {
|
||||
CommentTab[Addr] = xstrdup (Comment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* GetComment (unsigned Addr)
|
||||
/* Return the comment for an address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the label if any */
|
||||
return CommentTab[Addr];
|
||||
}
|
||||
|
||||
|
||||
|
63
src/da65/comments.h
Normal file
63
src/da65/comments.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* comments.h */
|
||||
/* */
|
||||
/* Comment management for da65 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2006 Ullrich von Bassewitz */
|
||||
/* Römerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef COMMENTS_H
|
||||
#define COMMENTS_H
|
||||
|
||||
|
||||
|
||||
#include "attrtab.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void SetComment (unsigned Addr, const char* Comment);
|
||||
/* Set a comment for the given address */
|
||||
|
||||
const char* GetComment (unsigned Addr);
|
||||
/* Return the comment for an address */
|
||||
|
||||
|
||||
|
||||
/* End of comments.h */
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "code.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "labels.h"
|
||||
#include "output.h"
|
||||
#include "data.h"
|
||||
|
||||
@ -174,13 +175,8 @@ unsigned AddrTable (void)
|
||||
break;
|
||||
}
|
||||
|
||||
/* More than one byte left. Check if there is a label defined within
|
||||
* the address word.
|
||||
*/
|
||||
if (MustDefLabel (PC+1)) {
|
||||
/* Define the label */
|
||||
DefineConst (GetLabel (PC+1), GetComment (PC+1), PC+1);
|
||||
}
|
||||
/* More than one byte left. Define a forward label if necessary */
|
||||
ForwardLabel (1);
|
||||
|
||||
/* Now get the address from the PC */
|
||||
Addr = GetCodeWord (PC);
|
||||
@ -191,7 +187,7 @@ unsigned AddrTable (void)
|
||||
AddIntLabel (Addr);
|
||||
}
|
||||
} else {
|
||||
const char* Label = GetLabel (Addr);
|
||||
const char* Label = GetLabel (Addr, PC);
|
||||
if (Label == 0) {
|
||||
/* OOPS! Should not happen */
|
||||
Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
|
||||
@ -244,13 +240,8 @@ unsigned RtsTable (void)
|
||||
break;
|
||||
}
|
||||
|
||||
/* More than one byte left. Check if there is a label defined within
|
||||
* the address word.
|
||||
*/
|
||||
if (MustDefLabel (PC+1)) {
|
||||
/* Define the label */
|
||||
DefineConst (GetLabel (PC+1), GetComment (PC+1), PC+1);
|
||||
}
|
||||
/* More than one byte left. Define a forward label if necessary */
|
||||
ForwardLabel (1);
|
||||
|
||||
/* Now get the address from the PC */
|
||||
Addr = (GetCodeWord (PC) + 1) & 0xFFFF;
|
||||
@ -261,7 +252,7 @@ unsigned RtsTable (void)
|
||||
AddIntLabel (Addr);
|
||||
}
|
||||
} else {
|
||||
const char* Label = GetLabel (Addr);
|
||||
const char* Label = GetLabel (Addr, PC);
|
||||
if (Label == 0) {
|
||||
/* OOPS! Should not happen */
|
||||
Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "handler.h"
|
||||
#include "labels.h"
|
||||
#include "opctable.h"
|
||||
#include "output.h"
|
||||
|
||||
@ -109,7 +110,7 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr)
|
||||
{
|
||||
const char* Label = 0;
|
||||
if (Flags & flUseLabel) {
|
||||
Label = GetLabel (Addr);
|
||||
Label = GetLabel (Addr, PC);
|
||||
}
|
||||
if (Label) {
|
||||
return Label;
|
||||
@ -147,6 +148,10 @@ static void GenerateLabel (unsigned Flags, unsigned Addr)
|
||||
/* Just add the label */
|
||||
AddIntLabel (Addr);
|
||||
} else {
|
||||
|
||||
/* THIS CODE IS A MESS AND WILL FAIL ON SEVERAL CONDITIONS! ### */
|
||||
|
||||
|
||||
/* Search for the start of the range or the last non dependent
|
||||
* label in the range.
|
||||
*/
|
||||
@ -161,8 +166,7 @@ static void GenerateLabel (unsigned Flags, unsigned Addr)
|
||||
}
|
||||
--LabelAddr;
|
||||
LabelAttr = GetLabelAttr (LabelAddr);
|
||||
if ((LabelAttr & (atIntLabel|atExtLabel)) != 0 &&
|
||||
(LabelAttr & atDepLabel) == 0) {
|
||||
if ((LabelAttr & (atIntLabel|atExtLabel)) != 0) {
|
||||
/* The address has an internal or external label */
|
||||
break;
|
||||
}
|
||||
@ -178,7 +182,7 @@ static void GenerateLabel (unsigned Flags, unsigned Addr)
|
||||
if (Offs == 0) {
|
||||
AddIntLabel (Addr);
|
||||
} else {
|
||||
AddDepLabel (Addr, atIntLabel, GetLabel (LabelAddr), Offs);
|
||||
AddDepLabel (Addr, atIntLabel, GetLabelName (LabelAddr), Offs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,9 +51,11 @@
|
||||
/* da65 */
|
||||
#include "asminc.h"
|
||||
#include "attrtab.h"
|
||||
#include "comments.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "infofile.h"
|
||||
#include "labels.h"
|
||||
#include "opctable.h"
|
||||
#include "scanner.h"
|
||||
|
||||
@ -357,8 +359,15 @@ static void RangeSection (void)
|
||||
|
||||
/* Do we have a label? */
|
||||
if (Attributes & tName) {
|
||||
|
||||
/* Define a label for the table */
|
||||
AddExtLabel (Start, Name, Comment);
|
||||
AddExtLabel (Start, Name);
|
||||
|
||||
/* Set the comment if we have one */
|
||||
if (Comment) {
|
||||
SetComment (Start, Comment);
|
||||
}
|
||||
|
||||
/* Delete name and comment */
|
||||
xfree (Name);
|
||||
xfree (Comment);
|
||||
@ -406,7 +415,7 @@ static void LabelSection (void)
|
||||
if (Value >= 0) {
|
||||
InfoError ("Value already given");
|
||||
}
|
||||
InfoAssureInt ();
|
||||
InfoAssureInt ();
|
||||
InfoRangeCheck (0, 0xFFFF);
|
||||
Value = InfoIVal;
|
||||
InfoNextTok ();
|
||||
@ -430,10 +439,7 @@ static void LabelSection (void)
|
||||
if (Name) {
|
||||
InfoError ("Name already given");
|
||||
}
|
||||
InfoAssureStr ();
|
||||
if (InfoSVal[0] == '\0') {
|
||||
InfoError ("Name may not be empty");
|
||||
}
|
||||
InfoAssureStr ();
|
||||
Name = xstrdup (InfoSVal);
|
||||
InfoNextTok ();
|
||||
break;
|
||||
@ -444,20 +450,23 @@ static void LabelSection (void)
|
||||
InfoError ("Size already given");
|
||||
}
|
||||
InfoAssureInt ();
|
||||
InfoRangeCheck (1, 0x10000);
|
||||
InfoRangeCheck (1, 0x10000);
|
||||
Size = InfoIVal;
|
||||
InfoNextTok ();
|
||||
break;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Directive is followed by a semicolon */
|
||||
InfoConsumeSemi ();
|
||||
/* Directive is followed by a semicolon */
|
||||
InfoConsumeSemi ();
|
||||
}
|
||||
|
||||
/* Did we get the necessary data */
|
||||
if (Name == 0) {
|
||||
InfoError ("Label name is missing");
|
||||
InfoError ("Label name is missing");
|
||||
}
|
||||
if (Name[0] == '\0' && Size > 1) {
|
||||
InfoError ("Unnamed labels must not have a size > 1");
|
||||
}
|
||||
if (Value < 0) {
|
||||
InfoError ("Label value is missing");
|
||||
@ -474,7 +483,17 @@ static void LabelSection (void)
|
||||
}
|
||||
|
||||
/* Define the label(s) */
|
||||
AddExtLabelRange ((unsigned) Value, Name, Comment, Size);
|
||||
if (Name[0] == '\0') {
|
||||
/* Size has already beed checked */
|
||||
AddUnnamedLabel (Value);
|
||||
} else {
|
||||
AddExtLabelRange ((unsigned) Value, Name, Size);
|
||||
}
|
||||
|
||||
/* Define the comment */
|
||||
if (Comment) {
|
||||
SetComment (Value, Comment);
|
||||
}
|
||||
|
||||
/* Delete the dynamically allocated memory for Name and Comment */
|
||||
xfree (Name);
|
||||
|
415
src/da65/labels.c
Normal file
415
src/da65/labels.c
Normal file
@ -0,0 +1,415 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* labels.c */
|
||||
/* */
|
||||
/* Label management for da65 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2006 Ullrich von Bassewitz */
|
||||
/* Römerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "xmalloc.h"
|
||||
#include "xsprintf.h"
|
||||
|
||||
/* da65 */
|
||||
#include "attrtab.h"
|
||||
#include "code.h"
|
||||
#include "comments.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "labels.h"
|
||||
#include "output.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Symbol table */
|
||||
static const char* SymTab[0x10000];
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static const char* MakeLabelName (unsigned Addr)
|
||||
/* Make the default label name from the given address and return it in a
|
||||
* static buffer.
|
||||
*/
|
||||
{
|
||||
static char LabelBuf [32];
|
||||
xsprintf (LabelBuf, sizeof (LabelBuf), "L%04X", Addr);
|
||||
return LabelBuf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
|
||||
/* Add a label */
|
||||
{
|
||||
/* Get an existing label attribute */
|
||||
attr_t ExistingAttr = GetLabelAttr (Addr);
|
||||
|
||||
/* Must not have two symbols for one address */
|
||||
if (ExistingAttr != atNoLabel) {
|
||||
/* 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) || strcmp (SymTab[Addr], Name) == 0)) {
|
||||
return;
|
||||
}
|
||||
Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr], Name);
|
||||
}
|
||||
|
||||
/* Create a new label (xstrdup will return NULL if input NULL) */
|
||||
SymTab[Addr] = xstrdup (Name);
|
||||
|
||||
/* Remember the attribute */
|
||||
MarkAddr (Addr, Attr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddIntLabel (unsigned Addr)
|
||||
/* Add an internal label using the address to generate the name. */
|
||||
{
|
||||
AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddExtLabel (unsigned Addr, const char* Name)
|
||||
/* Add an external label */
|
||||
{
|
||||
AddLabel (Addr, atExtLabel, Name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddUnnamedLabel (unsigned Addr)
|
||||
/* Add an unnamed label */
|
||||
{
|
||||
AddLabel (Addr, atUnnamedLabel, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs)
|
||||
/* Add a dependent label at the given address using "basename+Offs" as the new
|
||||
* name.
|
||||
*/
|
||||
{
|
||||
/* Allocate memory for the dependent label name */
|
||||
unsigned NameLen = strlen (BaseName);
|
||||
char* DepName = xmalloc (NameLen + 7); /* "+$ABCD\0" */
|
||||
|
||||
/* Create the new name in the buffer */
|
||||
if (UseHexOffs) {
|
||||
sprintf (DepName, "%s+$%02X", BaseName, Offs);
|
||||
} else {
|
||||
sprintf (DepName, "%s+%u", BaseName, Offs);
|
||||
}
|
||||
|
||||
/* Define the labels */
|
||||
AddLabel (Addr, Attr | atDepLabel, DepName);
|
||||
|
||||
/* Free the name buffer */
|
||||
xfree (DepName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void AddLabelRange (unsigned Addr, attr_t Attr,
|
||||
const char* Name, unsigned Count)
|
||||
/* Add a label for a range. The first entry gets the label "Name" while the
|
||||
* others get "Name+offs".
|
||||
*/
|
||||
{
|
||||
/* Define the label */
|
||||
AddLabel (Addr, Attr, Name);
|
||||
|
||||
/* Define dependent labels if necessary */
|
||||
if (Count > 1) {
|
||||
unsigned Offs;
|
||||
|
||||
/* Setup the format string */
|
||||
const char* Format = UseHexOffs? "$%02X" : "%u";
|
||||
|
||||
/* Allocate memory for the dependent label names */
|
||||
unsigned NameLen = strlen (Name);
|
||||
char* DepName = xmalloc (NameLen + 7); /* "+$ABCD" */
|
||||
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 < Count; ++Offs) {
|
||||
sprintf (DepOffs, Format, Offs);
|
||||
AddLabel (Addr + Offs, Attr | atDepLabel, DepName);
|
||||
}
|
||||
|
||||
/* Free the name buffer */
|
||||
xfree (DepName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count)
|
||||
/* Add an internal label for a range. The first entry gets the label "Name"
|
||||
* while the others get "Name+offs".
|
||||
*/
|
||||
{
|
||||
/* Define the label range */
|
||||
AddLabelRange (Addr, atIntLabel, Name, Count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count)
|
||||
/* Add an external label for a range. The first entry gets the label "Name"
|
||||
* while the others get "Name+offs".
|
||||
*/
|
||||
{
|
||||
/* Define the label range */
|
||||
AddLabelRange (Addr, atExtLabel, Name, Count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int HaveLabel (unsigned Addr)
|
||||
/* Check if there is a label for the given address */
|
||||
{
|
||||
/* Check for a label */
|
||||
return (GetLabelAttr (Addr) != atNoLabel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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, external, or unnamed label */
|
||||
return (A == atExtLabel || A == atIntLabel || A == atUnnamedLabel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* GetLabelName (unsigned Addr)
|
||||
/* Return the label name for an address */
|
||||
{
|
||||
/* Get the label attribute */
|
||||
attr_t A = GetLabelAttr (Addr);
|
||||
|
||||
/* Special case unnamed labels, because these don't have a named stored in
|
||||
* the symbol table to save space.
|
||||
*/
|
||||
if (A == atUnnamedLabel) {
|
||||
return "";
|
||||
} else {
|
||||
/* Return the label if any */
|
||||
return SymTab[Addr];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* GetLabel (unsigned Addr, unsigned RefFrom)
|
||||
/* Return the label name for an address, as it is used in a label reference.
|
||||
* RefFrom is the address the label is referenced from. This is needed in case
|
||||
* of unnamed labels, to determine the name.
|
||||
*/
|
||||
{
|
||||
static const char* FwdLabels[] = {
|
||||
":+", ":++", ":+++", ":++++", ":+++++", ":++++++", ":+++++++",
|
||||
":++++++++", ":+++++++++", ":++++++++++"
|
||||
};
|
||||
static const char* BackLabels[] = {
|
||||
":-", ":--", ":---", ":----", ":-----", ":------", ":-------",
|
||||
":--------", ":---------", ":----------"
|
||||
};
|
||||
|
||||
/* Get the label attribute */
|
||||
attr_t A = GetLabelAttr (Addr);
|
||||
|
||||
/* Special case unnamed labels, because these don't have a named stored in
|
||||
* the symbol table to save space.
|
||||
*/
|
||||
if (A == atUnnamedLabel) {
|
||||
|
||||
unsigned Count = 0;
|
||||
|
||||
/* Search forward or backward depending in which direction the label
|
||||
* is.
|
||||
*/
|
||||
if (Addr <= RefFrom) {
|
||||
/* Search backwards */
|
||||
unsigned I = RefFrom;
|
||||
while (Addr < I) {
|
||||
--I;
|
||||
A = GetLabelAttr (I);
|
||||
if (A == atUnnamedLabel) {
|
||||
++Count;
|
||||
if (Count >= sizeof (BackLabels) / sizeof (BackLabels[0])) {
|
||||
Error ("Too many unnamed labels between label at "
|
||||
"$%04X and reference at $%04X", Addr, RefFrom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the label name */
|
||||
return BackLabels[Count-1];
|
||||
|
||||
} else {
|
||||
/* Search forwards */
|
||||
unsigned I = RefFrom;
|
||||
while (Addr > I) {
|
||||
++I;
|
||||
A = GetLabelAttr (I);
|
||||
if (A == atUnnamedLabel) {
|
||||
++Count;
|
||||
if (Count >= sizeof (FwdLabels) / sizeof (FwdLabels[0])) {
|
||||
Error ("Too many unnamed labels between label at "
|
||||
"$%04X and reference at $%04X", Addr, RefFrom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the label name */
|
||||
return FwdLabels[Count-1];
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Return the label if any */
|
||||
return SymTab[Addr];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ForwardLabel (unsigned Offs)
|
||||
/* If necessary, output a forward label, one that is within the next few
|
||||
* bytes and is therefore output as "label = * + x".
|
||||
*/
|
||||
{
|
||||
/* Calculate the actual address */
|
||||
unsigned long Addr = PC + Offs;
|
||||
|
||||
/* Get the type of the label */
|
||||
attr_t A = GetLabelAttr (Addr);
|
||||
|
||||
/* If there is no label, or just a dependent one, bail out */
|
||||
if (A == atNoLabel || (A & atDepLabel) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* An unnamed label cannot be output as a forward declaration, so this is
|
||||
* an error.
|
||||
*/
|
||||
if (A == atUnnamedLabel) {
|
||||
Error ("Cannot define unnamed label at address $%04lX", Addr);
|
||||
}
|
||||
|
||||
/* Output the label */
|
||||
DefForward (GetLabelName (Addr), GetComment (Addr), Offs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DefOutOfRangeLabel (unsigned long Addr)
|
||||
/* Define one label that is outside code range. */
|
||||
{
|
||||
switch (GetLabelAttr (Addr)) {
|
||||
|
||||
case atIntLabel:
|
||||
case atExtLabel:
|
||||
DefineConst (SymTab[Addr], GetComment (Addr), Addr);
|
||||
break;
|
||||
|
||||
case atUnnamedLabel:
|
||||
Error ("Cannot define unnamed label at address $%04lX", Addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DefOutOfRangeLabels (void)
|
||||
/* Output any labels that are out of the loaded code range */
|
||||
{
|
||||
unsigned long Addr;
|
||||
|
||||
SeparatorLine ();
|
||||
|
||||
/* Low range */
|
||||
Addr = 0;
|
||||
while (Addr < CodeStart) {
|
||||
DefOutOfRangeLabel (Addr++);
|
||||
}
|
||||
|
||||
/* Skip areas in code range */
|
||||
while (Addr <= CodeEnd) {
|
||||
if (GetStyleAttr (Addr) == atSkip) {
|
||||
DefOutOfRangeLabel (Addr);
|
||||
}
|
||||
++Addr;
|
||||
}
|
||||
|
||||
/* High range */
|
||||
while (Addr < 0x10000) {
|
||||
DefOutOfRangeLabel (Addr++);
|
||||
}
|
||||
|
||||
SeparatorLine ();
|
||||
}
|
||||
|
||||
|
||||
|
106
src/da65/labels.h
Normal file
106
src/da65/labels.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* labels.h */
|
||||
/* */
|
||||
/* Label management for da65 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2006 Ullrich von Bassewitz */
|
||||
/* Römerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef LABELS_H
|
||||
#define LABELS_H
|
||||
|
||||
|
||||
|
||||
#include "attrtab.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void AddIntLabel (unsigned Addr);
|
||||
/* Add an internal label using the address to generate the name. */
|
||||
|
||||
void AddExtLabel (unsigned Addr, const char* Name);
|
||||
/* Add an external label */
|
||||
|
||||
void AddUnnamedLabel (unsigned Addr);
|
||||
/* Add an unnamed label */
|
||||
|
||||
void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs);
|
||||
/* Add a dependent label at the given address using "base name+Offs" as the new
|
||||
* name.
|
||||
*/
|
||||
|
||||
void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count);
|
||||
/* Add an internal label for a range. The first entry gets the label "Name"
|
||||
* while the others get "Name+offs".
|
||||
*/
|
||||
|
||||
void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count);
|
||||
/* Add an external label for a range. The first entry gets the label "Name"
|
||||
* while the others get "Name+offs".
|
||||
*/
|
||||
|
||||
int HaveLabel (unsigned Addr);
|
||||
/* Check if there is a label for the given 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.
|
||||
*/
|
||||
|
||||
const char* GetLabelName (unsigned Addr);
|
||||
/* Return the label name for an address */
|
||||
|
||||
const char* GetLabel (unsigned Addr, unsigned RefFrom);
|
||||
/* Return the label name for an address, as it is used in a label reference.
|
||||
* RefFrom is the address the label is referenced from. This is needed in case
|
||||
* of unnamed labels, to determine the name.
|
||||
*/
|
||||
|
||||
void ForwardLabel (unsigned Offs);
|
||||
/* If necessary, output a forward label, one that is within the next few
|
||||
* bytes and is therefore output as "label = * + x".
|
||||
*/
|
||||
|
||||
void DefOutOfRangeLabels (void);
|
||||
/* Output any labels that are out of the loaded code range */
|
||||
|
||||
|
||||
|
||||
/* End of labels.h */
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -51,10 +51,12 @@
|
||||
/* da65 */
|
||||
#include "attrtab.h"
|
||||
#include "code.h"
|
||||
#include "comments.h"
|
||||
#include "data.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "infofile.h"
|
||||
#include "labels.h"
|
||||
#include "opctable.h"
|
||||
#include "output.h"
|
||||
#include "scanner.h"
|
||||
@ -252,7 +254,7 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
||||
/* Print the disassembler version */
|
||||
{
|
||||
fprintf (stderr,
|
||||
"da65 V%u.%u.%u - (C) Copyright 2005 Ullrich von Bassewitz\n",
|
||||
"da65 V%u.%u.%u - (C) Copyright 2000-2006, Ullrich von Bassewitz\n",
|
||||
VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||
}
|
||||
|
||||
@ -278,7 +280,7 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
if (Comment) {
|
||||
UserComment (Comment);
|
||||
}
|
||||
DefLabel (GetLabel (PC));
|
||||
DefLabel (GetLabelName (PC));
|
||||
}
|
||||
|
||||
/* Check...
|
||||
@ -292,13 +294,13 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
} else if (D->Flags & flIllegal) {
|
||||
Style = atIllegal;
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
} else {
|
||||
unsigned I;
|
||||
for (I = 1; I < D->Size; ++I) {
|
||||
if (HaveLabel (PC+I)) {
|
||||
Style = atIllegal;
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
break;
|
||||
}
|
||||
@ -319,6 +321,11 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
* following insn, fall through to byte mode.
|
||||
*/
|
||||
if (D->Size <= RemainingBytes) {
|
||||
/* Output labels within the next insn */
|
||||
unsigned I;
|
||||
for (I = 1; I < D->Size; ++I) {
|
||||
ForwardLabel (I);
|
||||
}
|
||||
D->Handler (D);
|
||||
PC += D->Size;
|
||||
break;
|
||||
|
@ -13,11 +13,13 @@ LDFLAGS=
|
||||
OBJS = asminc.o \
|
||||
attrtab.o \
|
||||
code.o \
|
||||
comments.o \
|
||||
data.o \
|
||||
error.o \
|
||||
global.o \
|
||||
handler.o \
|
||||
infofile.o \
|
||||
labels.o \
|
||||
main.o \
|
||||
opc6502.o \
|
||||
opc65816.o \
|
||||
|
@ -63,11 +63,13 @@ endif
|
||||
OBJS = asminc.obj \
|
||||
attrtab.obj \
|
||||
code.obj \
|
||||
comments.obj \
|
||||
data.obj \
|
||||
error.obj \
|
||||
global.obj \
|
||||
handler.obj \
|
||||
infofile.obj \
|
||||
labels.obj \
|
||||
main.obj \
|
||||
opc6502.obj \
|
||||
opc65816.obj \
|
||||
|
@ -176,6 +176,46 @@ void DefLabel (const char* Name)
|
||||
|
||||
|
||||
|
||||
void DefForward (const char* Name, const char* Comment, unsigned Offs)
|
||||
/* Define a label as "* + x", where x is the offset relative to the
|
||||
* current PC.
|
||||
*/
|
||||
{
|
||||
if (Pass == PassCount) {
|
||||
Output ("%s", Name);
|
||||
Indent (AIndent);
|
||||
if (UseHexOffs) {
|
||||
Output (":= * + $%04X", Offs);
|
||||
} else {
|
||||
Output (":= * + %u", Offs);
|
||||
}
|
||||
if (Comment) {
|
||||
Indent (CIndent);
|
||||
Output ("; %s", Comment);
|
||||
}
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DefineConst (const char* Name, const char* Comment, unsigned Addr)
|
||||
/* Define an address constant */
|
||||
{
|
||||
if (Pass == PassCount) {
|
||||
Output ("%s", Name);
|
||||
Indent (AIndent);
|
||||
Output (":= $%04X", Addr);
|
||||
if (Comment) {
|
||||
Indent (CIndent);
|
||||
Output ("; %s", Comment);
|
||||
}
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataByteLine (unsigned ByteCount)
|
||||
/* Output a line with bytes */
|
||||
{
|
||||
@ -322,20 +362,3 @@ void OutputSettings (void)
|
||||
|
||||
|
||||
|
||||
void DefineConst (const char* Name, const char* Comment, unsigned Addr)
|
||||
/* Define an address constant */
|
||||
{
|
||||
if (Pass == PassCount) {
|
||||
Output ("%s", Name);
|
||||
Indent (AIndent);
|
||||
Output (":= $%04X", Addr);
|
||||
if (Comment) {
|
||||
Indent (CIndent);
|
||||
Output ("; %s", Comment);
|
||||
}
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -67,6 +67,14 @@ void LineFeed (void);
|
||||
void DefLabel (const char* Name);
|
||||
/* Define a label with the given name */
|
||||
|
||||
void DefForward (const char* Name, const char* Comment, unsigned Offs);
|
||||
/* Define a label as "* + x", where x is the offset relative to the
|
||||
* current PC.
|
||||
*/
|
||||
|
||||
void DefineConst (const char* Name, const char* Comment, unsigned Addr);
|
||||
/* Define an address constant */
|
||||
|
||||
void OneDataByte (void);
|
||||
/* Output a .byte line with the current code byte */
|
||||
|
||||
@ -94,9 +102,6 @@ void LineComment (unsigned PC, unsigned Count);
|
||||
void OutputSettings (void);
|
||||
/* Output CPU and other settings */
|
||||
|
||||
void DefineConst (const char* Name, const char* Comment, unsigned Addr);
|
||||
/* Define an address constant */
|
||||
|
||||
|
||||
|
||||
/* End of output.h */
|
||||
|
Loading…
x
Reference in New Issue
Block a user