mirror of
https://github.com/cc65/cc65.git
synced 2025-01-25 11:30:06 +00:00
Started to add support for segments.
git-svn-id: svn://svn.cc65.org/cc65/trunk@3805 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
10efd998e0
commit
8db6dcd414
@ -66,6 +66,19 @@ void AddrCheck (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int SegmentDefined (unsigned Start, unsigned End)
|
||||||
|
/* Return true if the atSegment bit is set somewhere in the given range */
|
||||||
|
{
|
||||||
|
while (Start <= End) {
|
||||||
|
if (AttrTab[Start++] & atSegment) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetGranularity (attr_t Style)
|
unsigned GetGranularity (attr_t Style)
|
||||||
/* Get the granularity for the given style */
|
/* Get the granularity for the given style */
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,10 @@ typedef enum attr_t {
|
|||||||
atLabelDefined = 0x0100, /* True if we defined the label */
|
atLabelDefined = 0x0100, /* True if we defined the label */
|
||||||
|
|
||||||
atStyleMask = 0x000F, /* Output style */
|
atStyleMask = 0x000F, /* Output style */
|
||||||
atLabelMask = 0x00F0 /* Label information */
|
atLabelMask = 0x00F0, /* Label information */
|
||||||
|
|
||||||
|
/* Segment */
|
||||||
|
atSegment = 0x0100, /* Code is in a segment */
|
||||||
} attr_t;
|
} attr_t;
|
||||||
|
|
||||||
|
|
||||||
@ -83,6 +86,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 */
|
||||||
|
|
||||||
|
int SegmentDefined (unsigned Start, unsigned End);
|
||||||
|
/* Return true if the atSegment bit is set somewhere in the given range */
|
||||||
|
|
||||||
unsigned GetGranularity (attr_t Style);
|
unsigned GetGranularity (attr_t Style);
|
||||||
/* Get the granularity for the given style */
|
/* Get the granularity for the given style */
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2005 Ullrich von Bassewitz */
|
/* (C) 2000-2007 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@ -58,6 +58,7 @@
|
|||||||
#include "labels.h"
|
#include "labels.h"
|
||||||
#include "opctable.h"
|
#include "opctable.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
|
#include "segment.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -79,6 +80,99 @@ static void AddAttr (const char* Name, unsigned* Set, unsigned Attr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void AsmIncSection (void)
|
||||||
|
/* Parse a asminc section */
|
||||||
|
{
|
||||||
|
static const IdentTok LabelDefs[] = {
|
||||||
|
{ "COMMENTSTART", INFOTOK_COMMENTSTART },
|
||||||
|
{ "FILE", INFOTOK_FILE },
|
||||||
|
{ "IGNOREUNKNOWN", INFOTOK_IGNOREUNKNOWN },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Locals - initialize to avoid gcc warnings */
|
||||||
|
char* Name = 0;
|
||||||
|
int CommentStart = EOF;
|
||||||
|
int IgnoreUnknown = -1;
|
||||||
|
|
||||||
|
/* Skip the token */
|
||||||
|
InfoNextTok ();
|
||||||
|
|
||||||
|
/* Expect the opening curly brace */
|
||||||
|
InfoConsumeLCurly ();
|
||||||
|
|
||||||
|
/* Look for section tokens */
|
||||||
|
while (InfoTok != INFOTOK_RCURLY) {
|
||||||
|
|
||||||
|
/* Convert to special token */
|
||||||
|
InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Asminc directive");
|
||||||
|
|
||||||
|
/* Look at the token */
|
||||||
|
switch (InfoTok) {
|
||||||
|
|
||||||
|
case INFOTOK_COMMENTSTART:
|
||||||
|
InfoNextTok ();
|
||||||
|
if (CommentStart != EOF) {
|
||||||
|
InfoError ("Commentstart already given");
|
||||||
|
}
|
||||||
|
InfoAssureChar ();
|
||||||
|
CommentStart = (char) InfoIVal;
|
||||||
|
InfoNextTok ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INFOTOK_FILE:
|
||||||
|
InfoNextTok ();
|
||||||
|
if (Name) {
|
||||||
|
InfoError ("File name already given");
|
||||||
|
}
|
||||||
|
InfoAssureStr ();
|
||||||
|
if (InfoSVal[0] == '\0') {
|
||||||
|
InfoError ("File name may not be empty");
|
||||||
|
}
|
||||||
|
Name = xstrdup (InfoSVal);
|
||||||
|
InfoNextTok ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INFOTOK_IGNOREUNKNOWN:
|
||||||
|
InfoNextTok ();
|
||||||
|
if (IgnoreUnknown != -1) {
|
||||||
|
InfoError ("Ignoreunknown already specified");
|
||||||
|
}
|
||||||
|
InfoBoolToken ();
|
||||||
|
IgnoreUnknown = (InfoTok != INFOTOK_FALSE);
|
||||||
|
InfoNextTok ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Internal ("Unexpected token: %u", InfoTok);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Directive is followed by a semicolon */
|
||||||
|
InfoConsumeSemi ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for the necessary data and assume defaults */
|
||||||
|
if (Name == 0) {
|
||||||
|
InfoError ("File name is missing");
|
||||||
|
}
|
||||||
|
if (CommentStart == EOF) {
|
||||||
|
CommentStart = ';';
|
||||||
|
}
|
||||||
|
if (IgnoreUnknown == -1) {
|
||||||
|
IgnoreUnknown = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the file and read the symbol definitions */
|
||||||
|
AsmInc (Name, CommentStart, IgnoreUnknown);
|
||||||
|
|
||||||
|
/* Delete the dynamically allocated memory for Name */
|
||||||
|
xfree (Name);
|
||||||
|
|
||||||
|
/* Consume the closing brace */
|
||||||
|
InfoConsumeRCurly ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void GlobalSection (void)
|
static void GlobalSection (void)
|
||||||
/* Parse a global section */
|
/* Parse a global section */
|
||||||
{
|
{
|
||||||
@ -256,6 +350,134 @@ static void GlobalSection (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void LabelSection (void)
|
||||||
|
/* Parse a label section */
|
||||||
|
{
|
||||||
|
static const IdentTok LabelDefs[] = {
|
||||||
|
{ "COMMENT", INFOTOK_COMMENT },
|
||||||
|
{ "ADDR", INFOTOK_ADDR },
|
||||||
|
{ "NAME", INFOTOK_NAME },
|
||||||
|
{ "SIZE", INFOTOK_SIZE },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Locals - initialize to avoid gcc warnings */
|
||||||
|
char* Name = 0;
|
||||||
|
char* Comment = 0;
|
||||||
|
long Value = -1;
|
||||||
|
long Size = -1;
|
||||||
|
|
||||||
|
/* Skip the token */
|
||||||
|
InfoNextTok ();
|
||||||
|
|
||||||
|
/* Expect the opening curly brace */
|
||||||
|
InfoConsumeLCurly ();
|
||||||
|
|
||||||
|
/* Look for section tokens */
|
||||||
|
while (InfoTok != INFOTOK_RCURLY) {
|
||||||
|
|
||||||
|
/* Convert to special token */
|
||||||
|
InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label attribute");
|
||||||
|
|
||||||
|
/* Look at the token */
|
||||||
|
switch (InfoTok) {
|
||||||
|
|
||||||
|
case INFOTOK_ADDR:
|
||||||
|
InfoNextTok ();
|
||||||
|
if (Value >= 0) {
|
||||||
|
InfoError ("Value already given");
|
||||||
|
}
|
||||||
|
InfoAssureInt ();
|
||||||
|
InfoRangeCheck (0, 0xFFFF);
|
||||||
|
Value = InfoIVal;
|
||||||
|
InfoNextTok ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INFOTOK_COMMENT:
|
||||||
|
InfoNextTok ();
|
||||||
|
if (Comment) {
|
||||||
|
InfoError ("Comment already given");
|
||||||
|
}
|
||||||
|
InfoAssureStr ();
|
||||||
|
if (InfoSVal[0] == '\0') {
|
||||||
|
InfoError ("Comment may not be empty");
|
||||||
|
}
|
||||||
|
Comment = xstrdup (InfoSVal);
|
||||||
|
InfoNextTok ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INFOTOK_NAME:
|
||||||
|
InfoNextTok ();
|
||||||
|
if (Name) {
|
||||||
|
InfoError ("Name already given");
|
||||||
|
}
|
||||||
|
InfoAssureStr ();
|
||||||
|
Name = xstrdup (InfoSVal);
|
||||||
|
InfoNextTok ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INFOTOK_SIZE:
|
||||||
|
InfoNextTok ();
|
||||||
|
if (Size >= 0) {
|
||||||
|
InfoError ("Size already given");
|
||||||
|
}
|
||||||
|
InfoAssureInt ();
|
||||||
|
InfoRangeCheck (1, 0x10000);
|
||||||
|
Size = InfoIVal;
|
||||||
|
InfoNextTok ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Internal ("Unexpected token: %u", InfoTok);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Directive is followed by a semicolon */
|
||||||
|
InfoConsumeSemi ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we get the necessary data */
|
||||||
|
if (Name == 0) {
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
if (Size < 0) {
|
||||||
|
/* Use default */
|
||||||
|
Size = 1;
|
||||||
|
}
|
||||||
|
if (Value + Size > 0x10000) {
|
||||||
|
InfoError ("Invalid size (address out of range)");
|
||||||
|
}
|
||||||
|
if (HaveLabel ((unsigned) Value)) {
|
||||||
|
InfoError ("Label for address $%04lX already defined", Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define the label(s) */
|
||||||
|
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);
|
||||||
|
xfree (Comment);
|
||||||
|
|
||||||
|
/* Consume the closing brace */
|
||||||
|
InfoConsumeRCurly ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void RangeSection (void)
|
static void RangeSection (void)
|
||||||
/* Parse a range section */
|
/* Parse a range section */
|
||||||
{
|
{
|
||||||
@ -311,7 +533,7 @@ static void RangeSection (void)
|
|||||||
while (InfoTok != INFOTOK_RCURLY) {
|
while (InfoTok != INFOTOK_RCURLY) {
|
||||||
|
|
||||||
/* Convert to special token */
|
/* Convert to special token */
|
||||||
InfoSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive");
|
InfoSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range attribute");
|
||||||
|
|
||||||
/* Look at the token */
|
/* Look at the token */
|
||||||
switch (InfoTok) {
|
switch (InfoTok) {
|
||||||
@ -425,21 +647,19 @@ static void RangeSection (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void LabelSection (void)
|
static void SegmentSection (void)
|
||||||
/* Parse a label section */
|
/* Parse a segment section */
|
||||||
{
|
{
|
||||||
static const IdentTok LabelDefs[] = {
|
static const IdentTok LabelDefs[] = {
|
||||||
{ "COMMENT", INFOTOK_COMMENT },
|
{ "END", INFOTOK_END },
|
||||||
{ "ADDR", INFOTOK_ADDR },
|
|
||||||
{ "NAME", INFOTOK_NAME },
|
{ "NAME", INFOTOK_NAME },
|
||||||
{ "SIZE", INFOTOK_SIZE },
|
{ "START", INFOTOK_START },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Locals - initialize to avoid gcc warnings */
|
/* Locals - initialize to avoid gcc warnings */
|
||||||
char* Name = 0;
|
long End = -1;
|
||||||
char* Comment = 0;
|
long Start = -1;
|
||||||
long Value = -1;
|
char* Name = 0;
|
||||||
long Size = -1;
|
|
||||||
|
|
||||||
/* Skip the token */
|
/* Skip the token */
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
@ -450,34 +670,21 @@ static void LabelSection (void)
|
|||||||
/* Look for section tokens */
|
/* Look for section tokens */
|
||||||
while (InfoTok != INFOTOK_RCURLY) {
|
while (InfoTok != INFOTOK_RCURLY) {
|
||||||
|
|
||||||
/* Convert to special token */
|
/* Convert to special token */
|
||||||
InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label directive");
|
InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Segment attribute");
|
||||||
|
|
||||||
/* Look at the token */
|
/* Look at the token */
|
||||||
switch (InfoTok) {
|
switch (InfoTok) {
|
||||||
|
|
||||||
case INFOTOK_ADDR:
|
case INFOTOK_END:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
if (Value >= 0) {
|
if (End >= 0) {
|
||||||
InfoError ("Value already given");
|
InfoError ("Value already given");
|
||||||
}
|
}
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0, 0xFFFF);
|
InfoRangeCheck (0, 0xFFFF);
|
||||||
Value = InfoIVal;
|
End = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
|
||||||
|
|
||||||
case INFOTOK_COMMENT:
|
|
||||||
InfoNextTok ();
|
|
||||||
if (Comment) {
|
|
||||||
InfoError ("Comment already given");
|
|
||||||
}
|
|
||||||
InfoAssureStr ();
|
|
||||||
if (InfoSVal[0] == '\0') {
|
|
||||||
InfoError ("Comment may not be empty");
|
|
||||||
}
|
|
||||||
Comment = xstrdup (InfoSVal);
|
|
||||||
InfoNextTok ();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFOTOK_NAME:
|
case INFOTOK_NAME:
|
||||||
@ -490,16 +697,16 @@ static void LabelSection (void)
|
|||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFOTOK_SIZE:
|
case INFOTOK_START:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
if (Size >= 0) {
|
if (Start >= 0) {
|
||||||
InfoError ("Size already given");
|
InfoError ("Value already given");
|
||||||
}
|
}
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (1, 0x10000);
|
InfoRangeCheck (0, 0xFFFF);
|
||||||
Size = InfoIVal;
|
Start = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Unexpected token: %u", InfoTok);
|
Internal ("Unexpected token: %u", InfoTok);
|
||||||
@ -509,133 +716,30 @@ static void LabelSection (void)
|
|||||||
InfoConsumeSemi ();
|
InfoConsumeSemi ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did we get the necessary data */
|
/* Did we get the necessary data, and is it correct? */
|
||||||
if (Name == 0) {
|
if (Name == 0 || Name[0] == '\0') {
|
||||||
InfoError ("Label name is missing");
|
InfoError ("Segment name is missing");
|
||||||
}
|
}
|
||||||
if (Name[0] == '\0' && Size > 1) {
|
if (End < 0) {
|
||||||
InfoError ("Unnamed labels must not have a size > 1");
|
InfoError ("End address is missing");
|
||||||
}
|
}
|
||||||
if (Value < 0) {
|
if (Start < 0) {
|
||||||
InfoError ("Label value is missing");
|
InfoError ("Start address is missing");
|
||||||
}
|
}
|
||||||
if (Size < 0) {
|
if (Start == End) {
|
||||||
/* Use default */
|
InfoError ("Segment is empty");
|
||||||
Size = 1;
|
|
||||||
}
|
}
|
||||||
if (Value + Size > 0x10000) {
|
if (Start > End) {
|
||||||
InfoError ("Invalid size (address out of range)");
|
InfoError ("Start address of segment is greater than end address");
|
||||||
}
|
|
||||||
if (HaveLabel ((unsigned) Value)) {
|
|
||||||
InfoError ("Label for address $%04lX already defined", Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define the label(s) */
|
/* Check that segments do not overlap */
|
||||||
if (Name[0] == '\0') {
|
if (SegmentDefined ((unsigned) Start, (unsigned) End)) {
|
||||||
/* Size has already beed checked */
|
InfoError ("Segments cannot overlap");
|
||||||
AddUnnamedLabel (Value);
|
|
||||||
} else {
|
|
||||||
AddExtLabelRange ((unsigned) Value, Name, Size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define the comment */
|
/* Remember the segment data */
|
||||||
if (Comment) {
|
AddAbsSegment ((unsigned) Start, (unsigned) End, Name);
|
||||||
SetComment (Value, Comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete the dynamically allocated memory for Name and Comment */
|
|
||||||
xfree (Name);
|
|
||||||
xfree (Comment);
|
|
||||||
|
|
||||||
/* Consume the closing brace */
|
|
||||||
InfoConsumeRCurly ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void AsmIncSection (void)
|
|
||||||
/* Parse a asminc section */
|
|
||||||
{
|
|
||||||
static const IdentTok LabelDefs[] = {
|
|
||||||
{ "COMMENTSTART", INFOTOK_COMMENTSTART },
|
|
||||||
{ "FILE", INFOTOK_FILE },
|
|
||||||
{ "IGNOREUNKNOWN", INFOTOK_IGNOREUNKNOWN },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Locals - initialize to avoid gcc warnings */
|
|
||||||
char* Name = 0;
|
|
||||||
int CommentStart = EOF;
|
|
||||||
int IgnoreUnknown = -1;
|
|
||||||
|
|
||||||
/* Skip the token */
|
|
||||||
InfoNextTok ();
|
|
||||||
|
|
||||||
/* Expect the opening curly brace */
|
|
||||||
InfoConsumeLCurly ();
|
|
||||||
|
|
||||||
/* Look for section tokens */
|
|
||||||
while (InfoTok != INFOTOK_RCURLY) {
|
|
||||||
|
|
||||||
/* Convert to special token */
|
|
||||||
InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Asminc directive");
|
|
||||||
|
|
||||||
/* Look at the token */
|
|
||||||
switch (InfoTok) {
|
|
||||||
|
|
||||||
case INFOTOK_COMMENTSTART:
|
|
||||||
InfoNextTok ();
|
|
||||||
if (CommentStart != EOF) {
|
|
||||||
InfoError ("Commentstart already given");
|
|
||||||
}
|
|
||||||
InfoAssureChar ();
|
|
||||||
CommentStart = (char) InfoIVal;
|
|
||||||
InfoNextTok ();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INFOTOK_FILE:
|
|
||||||
InfoNextTok ();
|
|
||||||
if (Name) {
|
|
||||||
InfoError ("File name already given");
|
|
||||||
}
|
|
||||||
InfoAssureStr ();
|
|
||||||
if (InfoSVal[0] == '\0') {
|
|
||||||
InfoError ("File name may not be empty");
|
|
||||||
}
|
|
||||||
Name = xstrdup (InfoSVal);
|
|
||||||
InfoNextTok ();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INFOTOK_IGNOREUNKNOWN:
|
|
||||||
InfoNextTok ();
|
|
||||||
if (IgnoreUnknown != -1) {
|
|
||||||
InfoError ("Ignoreunknown already specified");
|
|
||||||
}
|
|
||||||
InfoBoolToken ();
|
|
||||||
IgnoreUnknown = (InfoTok != INFOTOK_FALSE);
|
|
||||||
InfoNextTok ();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Internal ("Unexpected token: %u", InfoTok);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Directive is followed by a semicolon */
|
|
||||||
InfoConsumeSemi ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for the necessary data and assume defaults */
|
|
||||||
if (Name == 0) {
|
|
||||||
InfoError ("File name is missing");
|
|
||||||
}
|
|
||||||
if (CommentStart == EOF) {
|
|
||||||
CommentStart = ';';
|
|
||||||
}
|
|
||||||
if (IgnoreUnknown == -1) {
|
|
||||||
IgnoreUnknown = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the file and read the symbol definitions */
|
|
||||||
AsmInc (Name, CommentStart, IgnoreUnknown);
|
|
||||||
|
|
||||||
/* Delete the dynamically allocated memory for Name */
|
/* Delete the dynamically allocated memory for Name */
|
||||||
xfree (Name);
|
xfree (Name);
|
||||||
@ -650,10 +754,11 @@ static void InfoParse (void)
|
|||||||
/* Parse the config file */
|
/* Parse the config file */
|
||||||
{
|
{
|
||||||
static const IdentTok Globals[] = {
|
static const IdentTok Globals[] = {
|
||||||
{ "GLOBAL", INFOTOK_GLOBAL },
|
|
||||||
{ "RANGE", INFOTOK_RANGE },
|
|
||||||
{ "LABEL", INFOTOK_LABEL },
|
|
||||||
{ "ASMINC", INFOTOK_ASMINC },
|
{ "ASMINC", INFOTOK_ASMINC },
|
||||||
|
{ "GLOBAL", INFOTOK_GLOBAL },
|
||||||
|
{ "LABEL", INFOTOK_LABEL },
|
||||||
|
{ "RANGE", INFOTOK_RANGE },
|
||||||
|
{ "SEGMENT", INFOTOK_SEGMENT },
|
||||||
};
|
};
|
||||||
|
|
||||||
while (InfoTok != INFOTOK_EOF) {
|
while (InfoTok != INFOTOK_EOF) {
|
||||||
@ -664,20 +769,24 @@ static void InfoParse (void)
|
|||||||
/* Check the token */
|
/* Check the token */
|
||||||
switch (InfoTok) {
|
switch (InfoTok) {
|
||||||
|
|
||||||
|
case INFOTOK_ASMINC:
|
||||||
|
AsmIncSection ();
|
||||||
|
break;
|
||||||
|
|
||||||
case INFOTOK_GLOBAL:
|
case INFOTOK_GLOBAL:
|
||||||
GlobalSection ();
|
GlobalSection ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFOTOK_RANGE:
|
|
||||||
RangeSection ();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INFOTOK_LABEL:
|
case INFOTOK_LABEL:
|
||||||
LabelSection ();
|
LabelSection ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFOTOK_ASMINC:
|
case INFOTOK_RANGE:
|
||||||
AsmIncSection ();
|
RangeSection ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INFOTOK_SEGMENT:
|
||||||
|
SegmentSection ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#
|
#
|
||||||
# gcc Makefile for da65
|
# gcc Makefile for da65
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -27,7 +27,8 @@ OBJS = asminc.o \
|
|||||||
opc65sc02.o \
|
opc65sc02.o \
|
||||||
opctable.o \
|
opctable.o \
|
||||||
output.o \
|
output.o \
|
||||||
scanner.o
|
scanner.o \
|
||||||
|
segment.o
|
||||||
|
|
||||||
LIBS = $(COMMON)/common.a
|
LIBS = $(COMMON)/common.a
|
||||||
|
|
||||||
|
@ -77,7 +77,8 @@ OBJS = asminc.obj \
|
|||||||
opc65sc02.obj \
|
opc65sc02.obj \
|
||||||
opctable.obj \
|
opctable.obj \
|
||||||
output.obj \
|
output.obj \
|
||||||
scanner.obj
|
scanner.obj \
|
||||||
|
segment.obj
|
||||||
|
|
||||||
|
|
||||||
LIBS = ../common/common.lib
|
LIBS = ../common/common.lib
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
/* (C) 2000-2007 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@ -65,6 +65,7 @@ typedef enum token_t {
|
|||||||
INFOTOK_RANGE,
|
INFOTOK_RANGE,
|
||||||
INFOTOK_LABEL,
|
INFOTOK_LABEL,
|
||||||
INFOTOK_ASMINC,
|
INFOTOK_ASMINC,
|
||||||
|
INFOTOK_SEGMENT,
|
||||||
|
|
||||||
/* Global section */
|
/* Global section */
|
||||||
INFOTOK_ARGUMENT_COLUMN,
|
INFOTOK_ARGUMENT_COLUMN,
|
||||||
@ -75,11 +76,11 @@ typedef enum token_t {
|
|||||||
INFOTOK_INPUTNAME,
|
INFOTOK_INPUTNAME,
|
||||||
INFOTOK_INPUTOFFS,
|
INFOTOK_INPUTOFFS,
|
||||||
INFOTOK_INPUTSIZE,
|
INFOTOK_INPUTSIZE,
|
||||||
INFOTOK_LABELBREAK,
|
INFOTOK_LABELBREAK,
|
||||||
INFOTOK_MNEMONIC_COLUMN,
|
INFOTOK_MNEMONIC_COLUMN,
|
||||||
INFOTOK_OUTPUTNAME,
|
INFOTOK_OUTPUTNAME,
|
||||||
INFOTOK_PAGELENGTH,
|
INFOTOK_PAGELENGTH,
|
||||||
INFOTOK_STARTADDR,
|
INFOTOK_STARTADDR,
|
||||||
INFOTOK_TEXT_COLUMN,
|
INFOTOK_TEXT_COLUMN,
|
||||||
|
|
||||||
/* Range section */
|
/* Range section */
|
||||||
|
109
src/da65/segment.c
Normal file
109
src/da65/segment.c
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* segment.c */
|
||||||
|
/* */
|
||||||
|
/* Segment handling for da65 */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (C) 2007 Ullrich von Bassewitz */
|
||||||
|
/* Roemerstrasse 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 <string.h>
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "addrsize.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
|
||||||
|
/* da65 */
|
||||||
|
#include "attrtab.h"
|
||||||
|
#include "segment.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Hash definitions */
|
||||||
|
#define HASH_SIZE 64 /* Must be power of two */
|
||||||
|
#define HASH_MASK (HASH_SIZE-1)
|
||||||
|
|
||||||
|
/* Segment definition */
|
||||||
|
typedef struct Segment Segment;
|
||||||
|
struct Segment {
|
||||||
|
Segment* NextStart; /* Pointer to next segment */
|
||||||
|
Segment* NextEnd; /* Pointer to next segment */
|
||||||
|
unsigned long Start;
|
||||||
|
unsigned long End;
|
||||||
|
unsigned AddrSize;
|
||||||
|
char Name[1]; /* Name, dynamically allocated */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Tables containing the segments. A segment is inserted using it's hash
|
||||||
|
* value. Collision is done by single linked lists.
|
||||||
|
*/
|
||||||
|
static Segment* StartTab[HASH_SIZE]; /* Table containing segment starts */
|
||||||
|
static Segment* EndTab[HASH_SIZE]; /* Table containing segment ends */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AddAbsSegment (unsigned Start, unsigned End, const char* Name)
|
||||||
|
/* Add an absolute segment to the segment table */
|
||||||
|
{
|
||||||
|
/* Get the length of the name */
|
||||||
|
unsigned Len = strlen (Name);
|
||||||
|
|
||||||
|
/* Create a new segment */
|
||||||
|
Segment* S = xmalloc (sizeof (Segment) + Len);
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
S->Start = Start;
|
||||||
|
S->End = End;
|
||||||
|
S->AddrSize = ADDR_SIZE_ABS;
|
||||||
|
memcpy (S->Name, Name, Len + 1);
|
||||||
|
|
||||||
|
/* Insert the segment into the hash tables */
|
||||||
|
S->NextStart = StartTab[Start & HASH_MASK];
|
||||||
|
StartTab[Start & HASH_MASK] = S;
|
||||||
|
S->NextEnd = EndTab[End & HASH_MASK];
|
||||||
|
EndTab[End & HASH_MASK] = S;
|
||||||
|
|
||||||
|
/* Mark the addresses within the segment */
|
||||||
|
MarkRange (Start, End, atSegment);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
57
src/da65/segment.h
Normal file
57
src/da65/segment.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* segment.h */
|
||||||
|
/* */
|
||||||
|
/* Segment handling for da65 */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (C) 2007 Ullrich von Bassewitz */
|
||||||
|
/* Roemerstrasse 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 SEGMENT_H
|
||||||
|
#define SEGMENT_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AddAbsSegment (unsigned Start, unsigned End, const char* Name);
|
||||||
|
/* Add an absolute segment to the segment table */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* End of segment.h */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user