Support additional o65 attributes.
Add a special ID for the cc65 operating system that is written to the OS field of the options header. git-svn-id: svn://svn.cc65.org/cc65/trunk@1254 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -104,17 +104,6 @@ unsigned SegDescCount; /* Number of entries in list */
|
|||||||
static BinDesc* BinFmtDesc = 0;
|
static BinDesc* BinFmtDesc = 0;
|
||||||
static O65Desc* O65FmtDesc = 0;
|
static O65Desc* O65FmtDesc = 0;
|
||||||
|
|
||||||
/* Attributes for the o65 format */
|
|
||||||
static unsigned O65Attr = 0;
|
|
||||||
#define OA_OS 0x0001
|
|
||||||
#define OA_TYPE 0x0002
|
|
||||||
#define OA_VERSION 0x0004
|
|
||||||
#define OA_OSVERSION 0x0008
|
|
||||||
#define OA_TEXT 0x0010
|
|
||||||
#define OA_DATA 0x0020
|
|
||||||
#define OA_BSS 0x0040
|
|
||||||
#define OA_ZP 0x0080
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -806,6 +795,8 @@ static void ParseO65 (void)
|
|||||||
{ "IMPORT", CFGTOK_IMPORT },
|
{ "IMPORT", CFGTOK_IMPORT },
|
||||||
{ "TYPE", CFGTOK_TYPE },
|
{ "TYPE", CFGTOK_TYPE },
|
||||||
{ "OS", CFGTOK_OS },
|
{ "OS", CFGTOK_OS },
|
||||||
|
{ "ID", CFGTOK_ID },
|
||||||
|
{ "VERSION", CFGTOK_VERSION },
|
||||||
};
|
};
|
||||||
static const IdentTok Types [] = {
|
static const IdentTok Types [] = {
|
||||||
{ "SMALL", CFGTOK_SMALL },
|
{ "SMALL", CFGTOK_SMALL },
|
||||||
@@ -817,6 +808,25 @@ static void ParseO65 (void)
|
|||||||
{ "CC65", CFGTOK_CC65 },
|
{ "CC65", CFGTOK_CC65 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Bitmask to remember the attributes we got already */
|
||||||
|
enum {
|
||||||
|
atNone = 0x0000,
|
||||||
|
atOS = 0x0001,
|
||||||
|
atOSVersion = 0x0002,
|
||||||
|
atType = 0x0004,
|
||||||
|
atImport = 0x0008,
|
||||||
|
atExport = 0x0010,
|
||||||
|
atID = 0x0020,
|
||||||
|
atVersion = 0x0040
|
||||||
|
};
|
||||||
|
unsigned AttrFlags = atNone;
|
||||||
|
|
||||||
|
/* Remember the attributes read */
|
||||||
|
unsigned OS = 0; /* Initialize to keep gcc happy */
|
||||||
|
unsigned ID = 0; /* Dito */
|
||||||
|
unsigned Version = 0;
|
||||||
|
|
||||||
|
/* Read the attributes */
|
||||||
while (CfgTok == CFGTOK_IDENT) {
|
while (CfgTok == CFGTOK_IDENT) {
|
||||||
|
|
||||||
/* Map the identifier to a token */
|
/* Map the identifier to a token */
|
||||||
@@ -832,6 +842,8 @@ static void ParseO65 (void)
|
|||||||
switch (AttrTok) {
|
switch (AttrTok) {
|
||||||
|
|
||||||
case CFGTOK_EXPORT:
|
case CFGTOK_EXPORT:
|
||||||
|
/* Remember we had this token (maybe more than once) */
|
||||||
|
AttrFlags |= atExport;
|
||||||
/* We expect an identifier */
|
/* We expect an identifier */
|
||||||
CfgAssureIdent ();
|
CfgAssureIdent ();
|
||||||
/* Check if the export symbol is also defined as an import. */
|
/* Check if the export symbol is also defined as an import. */
|
||||||
@@ -843,13 +855,15 @@ static void ParseO65 (void)
|
|||||||
* error message when checking it here.
|
* error message when checking it here.
|
||||||
*/
|
*/
|
||||||
if (O65GetExport (O65FmtDesc, CfgSVal) != 0) {
|
if (O65GetExport (O65FmtDesc, CfgSVal) != 0) {
|
||||||
CfgError ("Duplicate exported symbol: `%s'", CfgSVal);
|
CfgError ("Duplicate exported symbol: `%s'", CfgSVal);
|
||||||
}
|
}
|
||||||
/* Insert the symbol into the table */
|
/* Insert the symbol into the table */
|
||||||
O65SetExport (O65FmtDesc, CfgSVal);
|
O65SetExport (O65FmtDesc, CfgSVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CFGTOK_IMPORT:
|
case CFGTOK_IMPORT:
|
||||||
|
/* Remember we had this token (maybe more than once) */
|
||||||
|
AttrFlags |= atImport;
|
||||||
/* We expect an identifier */
|
/* We expect an identifier */
|
||||||
CfgAssureIdent ();
|
CfgAssureIdent ();
|
||||||
/* Check if the imported symbol is also defined as an export. */
|
/* Check if the imported symbol is also defined as an export. */
|
||||||
@@ -869,7 +883,7 @@ static void ParseO65 (void)
|
|||||||
|
|
||||||
case CFGTOK_TYPE:
|
case CFGTOK_TYPE:
|
||||||
/* Cannot have this attribute twice */
|
/* Cannot have this attribute twice */
|
||||||
FlagAttr (&O65Attr, OA_TYPE, "TYPE");
|
FlagAttr (&AttrFlags, atType, "TYPE");
|
||||||
/* Get the type of the executable */
|
/* Get the type of the executable */
|
||||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||||
switch (CfgTok) {
|
switch (CfgTok) {
|
||||||
@@ -889,28 +903,35 @@ static void ParseO65 (void)
|
|||||||
|
|
||||||
case CFGTOK_OS:
|
case CFGTOK_OS:
|
||||||
/* Cannot use this attribute twice */
|
/* Cannot use this attribute twice */
|
||||||
FlagAttr (&O65Attr, OA_OS, "OS");
|
FlagAttr (&AttrFlags, atOS, "OS");
|
||||||
/* Get the operating system */
|
/* Get the operating system */
|
||||||
CfgSpecialToken (OperatingSystems, ENTRY_COUNT (OperatingSystems), "OS type");
|
CfgSpecialToken (OperatingSystems, ENTRY_COUNT (OperatingSystems), "OS type");
|
||||||
switch (CfgTok) {
|
switch (CfgTok) {
|
||||||
|
case CFGTOK_LUNIX: OS = O65OS_LUNIX; break;
|
||||||
case CFGTOK_LUNIX:
|
case CFGTOK_OSA65: OS = O65OS_OSA65; break;
|
||||||
O65SetOS (O65FmtDesc, O65OS_LUNIX);
|
case CFGTOK_CC65: OS = O65OS_CC65; break;
|
||||||
break;
|
default: CfgError ("Unexpected OS token");
|
||||||
|
|
||||||
case CFGTOK_OSA65:
|
|
||||||
O65SetOS (O65FmtDesc, O65OS_OSA65);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFGTOK_CC65:
|
|
||||||
O65SetOS (O65FmtDesc, O65OS_CC65);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
CfgError ("Unexpected OS token");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CFGTOK_ID:
|
||||||
|
/* Cannot have this attribute twice */
|
||||||
|
FlagAttr (&AttrFlags, atID, "ID");
|
||||||
|
/* We're expecting a number in the 0..$FFFF range*/
|
||||||
|
CfgAssureInt ();
|
||||||
|
CfgRangeCheck (0, 0xFFFF);
|
||||||
|
ID = (unsigned) CfgIVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CFGTOK_VERSION:
|
||||||
|
/* Cannot have this attribute twice */
|
||||||
|
FlagAttr (&AttrFlags, atVersion, "VERSION");
|
||||||
|
/* We're expecting a number in byte range */
|
||||||
|
CfgAssureInt ();
|
||||||
|
CfgRangeCheck (0, 0xFF);
|
||||||
|
Version = (unsigned) CfgIVal;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FAIL ("Unexpected attribute token");
|
FAIL ("Unexpected attribute token");
|
||||||
|
|
||||||
@@ -920,6 +941,23 @@ static void ParseO65 (void)
|
|||||||
CfgNextTok ();
|
CfgNextTok ();
|
||||||
CfgOptionalComma ();
|
CfgOptionalComma ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if we have all mandatory attributes */
|
||||||
|
AttrCheck (AttrFlags, atOS, "OS");
|
||||||
|
|
||||||
|
/* Check for attributes that may not be combined */
|
||||||
|
if (OS == O65OS_CC65) {
|
||||||
|
if ((AttrFlags & (atImport | atExport)) != 0) {
|
||||||
|
CfgError ("OS type CC65 may not have imports or exports");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (AttrFlags & atID) {
|
||||||
|
CfgError ("Operating system does not support the ID attribute");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the O65 operating system to use */
|
||||||
|
O65SetOS (O65FmtDesc, OS, Version, ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -970,11 +1008,11 @@ static void ParseConDes (void)
|
|||||||
/* Parse the CONDES feature */
|
/* Parse the CONDES feature */
|
||||||
{
|
{
|
||||||
static const IdentTok Attributes [] = {
|
static const IdentTok Attributes [] = {
|
||||||
{ "SEGMENT", CFGTOK_SEGMENT },
|
{ "SEGMENT", CFGTOK_SEGMENT },
|
||||||
{ "LABEL", CFGTOK_LABEL },
|
{ "LABEL", CFGTOK_LABEL },
|
||||||
{ "COUNT", CFGTOK_COUNT },
|
{ "COUNT", CFGTOK_COUNT },
|
||||||
{ "TYPE", CFGTOK_TYPE },
|
{ "TYPE", CFGTOK_TYPE },
|
||||||
{ "ORDER", CFGTOK_ORDER },
|
{ "ORDER", CFGTOK_ORDER },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const IdentTok Types [] = {
|
static const IdentTok Types [] = {
|
||||||
|
|||||||
@@ -1008,31 +1008,31 @@ void O65SetOption (O65Desc* D, unsigned Type, const void* Data, unsigned DataLen
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void O65SetOS (O65Desc* D, unsigned OS)
|
void O65SetOS (O65Desc* D, unsigned OS, unsigned Version, unsigned Id)
|
||||||
/* Set an option describing the target operating system */
|
/* Set an option describing the target operating system */
|
||||||
{
|
{
|
||||||
static const unsigned char OSA65 [2] = { O65OS_OSA65, 0 };
|
/* Setup the option data */
|
||||||
static const unsigned char Lunix [2] = { O65OS_LUNIX, 0 };
|
unsigned char Opt[4];
|
||||||
static const unsigned char CC65 [4] = { O65OS_CC65, 0, 0, 0 };
|
Opt[0] = OS;
|
||||||
|
Opt[1] = Version;
|
||||||
|
|
||||||
/* Write the correct option */
|
/* Write the correct option length */
|
||||||
switch (OS) {
|
switch (OS) {
|
||||||
|
|
||||||
case O65OS_OSA65:
|
case O65OS_OSA65:
|
||||||
O65SetOption (D, O65OPT_OS, OSA65, sizeof (OSA65));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case O65OS_LUNIX:
|
case O65OS_LUNIX:
|
||||||
O65SetOption (D, O65OPT_OS, Lunix, sizeof (Lunix));
|
/* No id for these two */
|
||||||
|
O65SetOption (D, O65OPT_OS, Opt, 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O65OS_CC65:
|
case O65OS_CC65:
|
||||||
O65SetOption (D, O65OPT_OS, CC65, sizeof (CC65));
|
/* Set the 16 bit id */
|
||||||
|
Opt[2] = (unsigned char) Id;
|
||||||
|
Opt[3] = (unsigned char) (Id >> 8);
|
||||||
|
O65SetOption (D, O65OPT_OS, Opt, 4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Trying to set invalid O65 operating system: %u", OS);
|
Internal ("Trying to set invalid O65 operating system: %u", OS);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ void O65SetAlignment (O65Desc* D, unsigned Align);
|
|||||||
void O65SetOption (O65Desc* D, unsigned Type, const void* Data, unsigned DataLen);
|
void O65SetOption (O65Desc* D, unsigned Type, const void* Data, unsigned DataLen);
|
||||||
/* Set an o65 header option */
|
/* Set an o65 header option */
|
||||||
|
|
||||||
void O65SetOS (O65Desc* D, unsigned OS);
|
void O65SetOS (O65Desc* D, unsigned OS, unsigned Version, unsigned Id);
|
||||||
/* Set an option describing the target operating system */
|
/* Set an option describing the target operating system */
|
||||||
|
|
||||||
ExtSym* O65GetImport (O65Desc* D, const char* Ident);
|
ExtSym* O65GetImport (O65Desc* D, const char* Ident);
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ typedef enum {
|
|||||||
CFGTOK_EXPORT,
|
CFGTOK_EXPORT,
|
||||||
CFGTOK_IMPORT,
|
CFGTOK_IMPORT,
|
||||||
CFGTOK_OS,
|
CFGTOK_OS,
|
||||||
|
CFGTOK_ID,
|
||||||
|
CFGTOK_VERSION,
|
||||||
CFGTOK_FORMAT,
|
CFGTOK_FORMAT,
|
||||||
|
|
||||||
CFGTOK_LOAD,
|
CFGTOK_LOAD,
|
||||||
|
|||||||
Reference in New Issue
Block a user