mirror of
https://github.com/cc65/cc65.git
synced 2025-01-03 16:33:19 +00:00
Support for optionally specifying address size for segments with:
#pragma ***-name([push,] "name"[, "addrsize"]) where "addrsize" is any addressing size supported in ca65.
This commit is contained in:
parent
f8c9dde989
commit
e58c84acf7
@ -39,6 +39,7 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
/* common */
|
||||
#include "addrsize.h"
|
||||
#include "check.h"
|
||||
#include "cpu.h"
|
||||
#include "inttypes.h"
|
||||
@ -260,6 +261,9 @@ void g_usebss (void)
|
||||
void g_segname (segment_t Seg)
|
||||
/* Emit the name of a segment if necessary */
|
||||
{
|
||||
unsigned char AddrSize;
|
||||
const char* Name;
|
||||
|
||||
/* Emit a segment directive for the data style segments */
|
||||
DataSeg* S;
|
||||
switch (Seg) {
|
||||
@ -269,7 +273,13 @@ void g_segname (segment_t Seg)
|
||||
default: S = 0; break;
|
||||
}
|
||||
if (S) {
|
||||
DS_AddLine (S, ".segment\t\"%s\"", GetSegName (Seg));
|
||||
Name = GetSegName (Seg);
|
||||
AddrSize = GetSegAddrSize (Name);
|
||||
if (AddrSize != ADDR_SIZE_INVALID) {
|
||||
DS_AddLine (S, ".segment\t\"%s\": %s", Name, AddrSizeToStr (AddrSize));
|
||||
} else {
|
||||
DS_AddLine (S, ".segment\t\"%s\"", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,6 +897,9 @@ int main (int argc, char* argv[])
|
||||
/* Initialize the default segment names */
|
||||
InitSegNames ();
|
||||
|
||||
/* Initialize the segment address sizes table */
|
||||
InitSegAddrSizes ();
|
||||
|
||||
/* Initialize the include search paths */
|
||||
InitIncludePaths ();
|
||||
|
||||
@ -1089,6 +1092,9 @@ int main (int argc, char* argv[])
|
||||
/* Done with tracked string buffer allocation */
|
||||
DoneDiagnosticStrBufs ();
|
||||
|
||||
/* Free up the segment address sizes table */
|
||||
DoneSegAddrSizes ();
|
||||
|
||||
/* Return an apropriate exit code */
|
||||
return (ErrorCount > 0)? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "addrsize.h"
|
||||
#include "chartype.h"
|
||||
#include "segnames.h"
|
||||
#include "tgttrans.h"
|
||||
@ -389,7 +390,9 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
|
||||
/* Handle a pragma that expects a segment name parameter */
|
||||
{
|
||||
const char* Name;
|
||||
unsigned char AddrSize = ADDR_SIZE_INVALID;
|
||||
StrBuf S = AUTO_STRBUF_INITIALIZER;
|
||||
StrBuf A = AUTO_STRBUF_INITIALIZER;
|
||||
int Push = 0;
|
||||
|
||||
/* Check for the "push" or "pop" keywords */
|
||||
@ -430,13 +433,35 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
|
||||
goto ExitPoint;
|
||||
}
|
||||
|
||||
/* Get the string */
|
||||
/* Get the name string of the segment */
|
||||
Name = SB_GetConstBuf (&S);
|
||||
|
||||
/* Check if the name is valid */
|
||||
if (ValidSegName (Name)) {
|
||||
|
||||
/* Set the new name */
|
||||
/* Skip the following comma */
|
||||
SB_SkipWhite (B);
|
||||
if (SB_Peek (B) == ',') {
|
||||
SB_Skip (B);
|
||||
SB_SkipWhite (B);
|
||||
|
||||
/* A string argument must follow */
|
||||
if (!GetString (B, &A)) {
|
||||
goto ExitPoint;
|
||||
}
|
||||
|
||||
/* Get the address size for the segment */
|
||||
AddrSize = AddrSizeFromStr (SB_GetConstBuf (&A));
|
||||
|
||||
/* Set the address size for the segment if valid */
|
||||
if (AddrSize != ADDR_SIZE_INVALID) {
|
||||
SetSegAddrSize (Name, AddrSize);
|
||||
} else {
|
||||
Warning ("Invalid address size for segment!");
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the new name and optionally address size */
|
||||
if (Push) {
|
||||
PushSegName (Seg, Name);
|
||||
} else {
|
||||
@ -460,6 +485,7 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
|
||||
ExitPoint:
|
||||
/* Call the string buf destructor */
|
||||
SB_Done (&S);
|
||||
SB_Done (&A);
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "addrsize.h"
|
||||
#include "chartype.h"
|
||||
#include "check.h"
|
||||
#include "coll.h"
|
||||
@ -61,6 +62,13 @@
|
||||
|
||||
|
||||
|
||||
/* Table struct for address sizes of segments */
|
||||
typedef struct {
|
||||
StrBuf Name;
|
||||
unsigned char AddrSize;
|
||||
} SegAddrSize_t;
|
||||
|
||||
|
||||
/* Pointer to the current segment list. Output goes here. */
|
||||
Segments* CS = 0;
|
||||
|
||||
@ -70,6 +78,9 @@ Segments* GS = 0;
|
||||
/* Actual names for the segments */
|
||||
static StrStack SegmentNames[SEG_COUNT];
|
||||
|
||||
/* Address size for the segments */
|
||||
static Collection SegmentAddrSizes;
|
||||
|
||||
/* We're using a collection for the stack instead of a linked list. Since
|
||||
** functions may not be nested (at least in the current implementation), the
|
||||
** maximum stack depth is 2, so there is not really a need for a better
|
||||
@ -85,6 +96,85 @@ static Collection SegmentStack = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
|
||||
void InitSegAddrSizes (void)
|
||||
/* Initialize the segment address sizes */
|
||||
{
|
||||
InitCollection (&SegmentAddrSizes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DoneSegAddrSizes (void)
|
||||
/* Free the segment address sizes */
|
||||
{
|
||||
SegAddrSize_t* A;
|
||||
int I;
|
||||
for (I = 0; I < (int)CollCount (&SegmentAddrSizes); ++I) {
|
||||
A = CollAtUnchecked (&SegmentAddrSizes, I);
|
||||
SB_Done (&A->Name);
|
||||
xfree (A);
|
||||
}
|
||||
DoneCollection (&SegmentAddrSizes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static SegAddrSize_t* FindSegAddrSize (const char* Name)
|
||||
/* Find already specified address size for a segment by name.
|
||||
** Return the found struct or 0 if not found.
|
||||
*/
|
||||
{
|
||||
SegAddrSize_t* A;
|
||||
int I;
|
||||
for (I = 0; I < (int)CollCount (&SegmentAddrSizes); ++I) {
|
||||
A = CollAtUnchecked (&SegmentAddrSizes, I);
|
||||
if (A && strcmp (SB_GetConstBuf (&A->Name), Name) == 0) {
|
||||
return A;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SetSegAddrSize (const char* Name, unsigned char AddrSize)
|
||||
/* Set the address size for a segment */
|
||||
{
|
||||
SegAddrSize_t* A = FindSegAddrSize (Name);
|
||||
if (!A) {
|
||||
/* New one */
|
||||
A = xmalloc (sizeof (SegAddrSize_t));
|
||||
SB_Init (&A->Name);
|
||||
SB_CopyStr (&A->Name, Name);
|
||||
SB_Terminate (&A->Name);
|
||||
CollAppend (&SegmentAddrSizes, A);
|
||||
} else {
|
||||
/* Check for mismatching address sizes */
|
||||
if (A->AddrSize != AddrSize) {
|
||||
Warning ("Segment address size changed from last time!");
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the address size anyway */
|
||||
A->AddrSize = AddrSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char GetSegAddrSize (const char* Name)
|
||||
/* Get the address size of the given segment.
|
||||
** Return ADDR_SIZE_INVALID if not found.
|
||||
*/
|
||||
{
|
||||
SegAddrSize_t* A = FindSegAddrSize (Name);
|
||||
if (A) {
|
||||
return A->AddrSize;
|
||||
}
|
||||
return ADDR_SIZE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InitSegNames (void)
|
||||
/* Initialize the segment names */
|
||||
{
|
||||
|
@ -103,6 +103,19 @@ extern Segments* GS;
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
void InitSegAddrSizes (void);
|
||||
/* Initialize the segment address sizes */
|
||||
|
||||
void DoneSegAddrSizes (void);
|
||||
/* Free the segment address sizes */
|
||||
|
||||
void SetSegAddrSize (const char* Name, unsigned char AddrSize);
|
||||
/* Set the address size for a segment */
|
||||
|
||||
unsigned char GetSegAddrSize (const char* Name);
|
||||
/* Get the address size of the given segment.
|
||||
** Return ADDR_SIZE_INVALID if not found.
|
||||
*/
|
||||
|
||||
void InitSegNames (void);
|
||||
/* Initialize the segment names */
|
||||
|
Loading…
Reference in New Issue
Block a user