1
0
mirror of https://github.com/cc65/cc65.git synced 2024-11-17 09:07:32 +00:00

Only write full ATARI XEX header in the first chunk.

This commit is contained in:
Daniel Serpell 2018-09-25 20:21:49 -03:00
parent 8e3fe2ef86
commit 63d9b492b7
4 changed files with 89 additions and 2 deletions

View File

@ -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) static void ParseFormats (void)
/* Parse a target format section */ /* Parse a target format section */
{ {
@ -1009,6 +1069,7 @@ static void ParseFormats (void)
{ "O65", CFGTOK_O65 }, { "O65", CFGTOK_O65 },
{ "BIN", CFGTOK_BIN }, { "BIN", CFGTOK_BIN },
{ "BINARY", CFGTOK_BIN }, { "BINARY", CFGTOK_BIN },
{ "ATARI", CFGTOK_ATARIEXE },
}; };
while (CfgTok == CFGTOK_IDENT) { while (CfgTok == CFGTOK_IDENT) {
@ -1029,8 +1090,11 @@ static void ParseFormats (void)
ParseO65 (); ParseO65 ();
break; break;
case CFGTOK_BIN:
case CFGTOK_ATARIEXE: case CFGTOK_ATARIEXE:
ParseXex ();
break;
case CFGTOK_BIN:
/* No attribibutes available */ /* No attribibutes available */
break; break;

View File

@ -93,6 +93,7 @@ typedef enum {
CFGTOK_ID, CFGTOK_ID,
CFGTOK_VERSION, CFGTOK_VERSION,
CFGTOK_FORMAT, CFGTOK_FORMAT,
CFGTOK_RUNAD,
CFGTOK_LOAD, CFGTOK_LOAD,
CFGTOK_RUN, CFGTOK_RUN,

View File

@ -64,6 +64,7 @@ struct XexDesc {
unsigned Undef; /* Count of undefined externals */ unsigned Undef; /* Count of undefined externals */
FILE* F; /* Output file */ FILE* F; /* Output file */
const char* Filename; /* Name of output file */ const char* Filename; /* Name of output file */
Import* RunAd; /* Run Address */
}; };
@ -84,6 +85,7 @@ XexDesc* NewXexDesc (void)
D->Undef = 0; D->Undef = 0;
D->F = 0; D->F = 0;
D->Filename = 0; D->Filename = 0;
D->RunAd = 0;
/* Return the created struct */ /* Return the created struct */
return D; 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, static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size,
unsigned long Offs attribute ((unused)), unsigned long Offs attribute ((unused)),
void* Data) void* Data)
@ -173,7 +183,8 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M)
} }
/* Write header */ /* Write header */
Write16(D->F, 0xFFFF); if (ftell (D->F) == 0)
Write16(D->F, 0xFFFF);
Write16(D->F, M->Start); Write16(D->F, M->Start);
Write16(D->F, Addr-1); Write16(D->F, Addr-1);
@ -273,6 +284,7 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M)
WriteMult (D->F, M->FillVal, ToFill); WriteMult (D->F, M->FillVal, ToFill);
M->FillLevel = M->Size; M->FillLevel = M->Size;
} }
} }
@ -325,6 +337,13 @@ void XexWriteTarget (XexDesc* D, struct File* F)
XexWriteMem (D, M); 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 */ /* Close the file */
if (fclose (D->F) != 0) { if (fclose (D->F) != 0) {
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno)); Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));

View File

@ -36,6 +36,7 @@
#include "config.h" #include "config.h"
#include "exports.h"
@ -65,6 +66,8 @@ void FreeXexDesc (XexDesc* D);
void XexWriteTarget (XexDesc* D, File* F); void XexWriteTarget (XexDesc* D, File* F);
/* Write a XEX output file */ /* Write a XEX output file */
void XexSetRunAd (XexDesc* D, Import *RunAd);
/* Set the RUNAD export */
/* End of xex.h */ /* End of xex.h */