diff --git a/src/ld65/config.c b/src/ld65/config.c index fdf7d13eb..fafbed290 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -1002,6 +1002,66 @@ static void ParseO65 (void) +static void ParseXex (void) +/* Parse the o65 format section */ +{ + static const IdentTok Attributes [] = { + { "RUNAD", CFGTOK_RUNAD }, + }; + + /* Remember the attributes read */ + /* Bitmask to remember the attributes we got already */ + enum { + atNone = 0x0000, + atRunAd = 0x0001, + }; + unsigned AttrFlags = atNone; + Import *RunAd = 0; + + /* Read the attributes */ + while (CfgTok == CFGTOK_IDENT) { + + /* Map the identifier to a token */ + cfgtok_t AttrTok; + CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute"); + AttrTok = CfgTok; + + /* An optional assignment follows */ + CfgNextTok (); + CfgOptionalAssign (); + + /* Check which attribute was given */ + switch (AttrTok) { + + case CFGTOK_RUNAD: + /* Cannot have this attribute twice */ + FlagAttr (&AttrFlags, atRunAd, "RUNAD"); + /* We expect an identifier */ + CfgAssureIdent (); + /* Generate an import for the symbol */ + RunAd = InsertImport (GenImport (GetStrBufId (&CfgSVal), ADDR_SIZE_ABS)); + /* Remember the file position */ + CollAppend (&RunAd->RefLines, GenLineInfo (&CfgErrorPos)); + /* Eat the identifier token */ + CfgNextTok (); + break; + + default: + FAIL ("Unexpected attribute token"); + + } + + /* Skip an optional comma */ + CfgOptionalComma (); + } + + /* Set the RUNAD import if we have one */ + if ( RunAd ) + XexSetRunAd (XexFmtDesc, RunAd); +} + + + static void ParseFormats (void) /* Parse a target format section */ { @@ -1009,6 +1069,7 @@ static void ParseFormats (void) { "O65", CFGTOK_O65 }, { "BIN", CFGTOK_BIN }, { "BINARY", CFGTOK_BIN }, + { "ATARI", CFGTOK_ATARIEXE }, }; while (CfgTok == CFGTOK_IDENT) { @@ -1029,8 +1090,11 @@ static void ParseFormats (void) ParseO65 (); break; - case CFGTOK_BIN: case CFGTOK_ATARIEXE: + ParseXex (); + break; + + case CFGTOK_BIN: /* No attribibutes available */ break; diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 783685951..77fa91da8 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -93,6 +93,7 @@ typedef enum { CFGTOK_ID, CFGTOK_VERSION, CFGTOK_FORMAT, + CFGTOK_RUNAD, CFGTOK_LOAD, CFGTOK_RUN, diff --git a/src/ld65/xex.c b/src/ld65/xex.c index 71065ea57..9d373fb36 100644 --- a/src/ld65/xex.c +++ b/src/ld65/xex.c @@ -64,6 +64,7 @@ struct XexDesc { unsigned Undef; /* Count of undefined externals */ FILE* F; /* Output file */ const char* Filename; /* Name of output file */ + Import* RunAd; /* Run Address */ }; @@ -84,6 +85,7 @@ XexDesc* NewXexDesc (void) D->Undef = 0; D->F = 0; D->Filename = 0; + D->RunAd = 0; /* Return the created struct */ return D; @@ -99,6 +101,14 @@ void FreeXexDesc (XexDesc* D) +void XexSetRunAd (XexDesc* D, Import *RunAd) +/* Set the RUNAD export */ +{ + D->RunAd = RunAd; +} + + + static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size, unsigned long Offs attribute ((unused)), void* Data) @@ -173,7 +183,8 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) } /* Write header */ - Write16(D->F, 0xFFFF); + if (ftell (D->F) == 0) + Write16(D->F, 0xFFFF); Write16(D->F, M->Start); Write16(D->F, Addr-1); @@ -273,6 +284,7 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) WriteMult (D->F, M->FillVal, ToFill); M->FillLevel = M->Size; } + } @@ -325,6 +337,13 @@ void XexWriteTarget (XexDesc* D, struct File* F) XexWriteMem (D, M); } + /* Write RUNAD at file end */ + if (D->RunAd) { + Write16 (D->F, 0x2E0); + Write16 (D->F, 0x2E1); + Write16 (D->F, GetExportVal (D->RunAd->Exp)); + } + /* Close the file */ if (fclose (D->F) != 0) { Error ("Cannot write to `%s': %s", D->Filename, strerror (errno)); diff --git a/src/ld65/xex.h b/src/ld65/xex.h index fd6ba7201..c74f78eca 100644 --- a/src/ld65/xex.h +++ b/src/ld65/xex.h @@ -36,6 +36,7 @@ #include "config.h" +#include "exports.h" @@ -65,6 +66,8 @@ void FreeXexDesc (XexDesc* D); void XexWriteTarget (XexDesc* D, File* F); /* Write a XEX output file */ +void XexSetRunAd (XexDesc* D, Import *RunAd); +/* Set the RUNAD export */ /* End of xex.h */