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:
cuz
2002-04-21 20:00:04 +00:00
parent 1c3e74a148
commit 3f9e7b56ae
4 changed files with 88 additions and 48 deletions

View File

@@ -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. */
@@ -850,6 +862,8 @@ static void ParseO65 (void)
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);
} }

View File

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

View File

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

View File

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