mirror of
https://github.com/cc65/cc65.git
synced 2025-03-04 00:30:35 +00:00
Only write full ATARI XEX header in the first chunk.
This commit is contained in:
parent
8e3fe2ef86
commit
63d9b492b7
@ -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;
|
||||
|
||||
|
@ -93,6 +93,7 @@ typedef enum {
|
||||
CFGTOK_ID,
|
||||
CFGTOK_VERSION,
|
||||
CFGTOK_FORMAT,
|
||||
CFGTOK_RUNAD,
|
||||
|
||||
CFGTOK_LOAD,
|
||||
CFGTOK_RUN,
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user