Add support for INITAD to the Atari binary format.

This commit is contained in:
Daniel Serpell
2019-02-18 00:24:52 -03:00
parent 417ef278a3
commit b03ae76b54
8 changed files with 108 additions and 7 deletions

View File

@@ -1007,6 +1007,7 @@ static void ParseXex (void)
{
static const IdentTok Attributes [] = {
{ "RUNAD", CFGTOK_RUNAD },
{ "INITAD", CFGTOK_INITAD },
};
/* Remember the attributes read */
@@ -1017,6 +1018,8 @@ static void ParseXex (void)
};
unsigned AttrFlags = atNone;
Import *RunAd = 0;
Import *InitAd;
MemoryArea *InitMem;
/* Read the attributes */
while (CfgTok == CFGTOK_IDENT) {
@@ -1046,6 +1049,24 @@ static void ParseXex (void)
CfgNextTok ();
break;
case CFGTOK_INITAD:
/* We expect a memory area followed by a colon and an identifier */
CfgAssureIdent ();
InitMem = CfgGetMemory (GetStrBufId (&CfgSVal));
CfgNextTok ();
CfgConsumeColon ();
CfgAssureIdent ();
/* Generate an import for the symbol */
InitAd = InsertImport (GenImport (GetStrBufId (&CfgSVal), ADDR_SIZE_ABS));
/* Remember the file position */
CollAppend (&InitAd->RefLines, GenLineInfo (&CfgErrorPos));
/* Eat the identifier token */
CfgNextTok ();
/* Add to XEX */
if (XexAddInitAd (XexFmtDesc, InitMem, InitAd))
CfgError (&CfgErrorPos, "INITAD already given for memory area");
break;
default:
FAIL ("Unexpected attribute token");

View File

@@ -94,6 +94,7 @@ typedef enum {
CFGTOK_VERSION,
CFGTOK_FORMAT,
CFGTOK_RUNAD,
CFGTOK_INITAD,
CFGTOK_LOAD,
CFGTOK_RUN,

View File

@@ -58,6 +58,12 @@
/* Data */
/*****************************************************************************/
/* Linked list of memory area initialization addresses */
typedef struct XexInitAd {
MemoryArea *InitMem;
Import *InitAd;
struct XexInitAd *next;
} XexInitAd;
struct XexDesc {
@@ -65,13 +71,13 @@ struct XexDesc {
FILE* F; /* Output file */
const char* Filename; /* Name of output file */
Import* RunAd; /* Run Address */
XexInitAd* InitAds; /* List of Init Addresses */
unsigned long HeadPos; /* Position in the file of current header */
unsigned long HeadEnd; /* End address of current header */
unsigned long HeadSize; /* Last header size, can be removed if zero */
};
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@@ -89,6 +95,7 @@ XexDesc* NewXexDesc (void)
D->F = 0;
D->Filename = 0;
D->RunAd = 0;
D->InitAds = 0;
D->HeadPos = 0;
D->HeadEnd = 0;
D->HeadSize = 0;
@@ -113,8 +120,35 @@ void XexSetRunAd (XexDesc* D, Import *RunAd)
D->RunAd = RunAd;
}
XexInitAd* XexSearchInitMem(XexDesc* D, MemoryArea *InitMem)
{
XexInitAd* I;
for (I=D->InitAds; I != 0; I=I->next)
{
if (I->InitMem == InitMem)
return I;
}
return NULL;
}
int XexAddInitAd (XexDesc* D, MemoryArea *InitMem, Import *InitAd)
/* Sets and INITAD for the given memory area */
{
XexInitAd* I;
/* Search for repeated entry */
if (XexSearchInitMem (D, InitMem))
return 1;
I = xmalloc (sizeof (XexInitAd));
I->InitAd = InitAd;
I->InitMem = InitMem;
I->next = D->InitAds;
D->InitAds = I;
return 0;
}
static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size,
unsigned long Offs attribute ((unused)),
void* Data)
@@ -369,8 +403,15 @@ void XexWriteTarget (XexDesc* D, struct File* F)
for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
/* Get this entry */
MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I);
/* See if we have an init address for this area */
XexInitAd* I = XexSearchInitMem (D, M);
Print (stdout, 1, " ATARI EXE Dumping `%s'\n", GetString (M->Name));
XexWriteMem (D, M);
if (I) {
Write16 (D->F, 0x2E2);
Write16 (D->F, 0x2E3);
Write16 (D->F, GetExportVal (I->InitAd->Exp));
}
}
/* Write RUNAD at file end */

View File

@@ -69,6 +69,8 @@ void XexWriteTarget (XexDesc* D, File* F);
void XexSetRunAd (XexDesc* D, Import *RunAd);
/* Set the RUNAD export */
int XexAddInitAd (XexDesc* D, MemoryArea *InitMem, Import *InitAd);
/* Sets and INITAD for the given memory area */
/* End of xex.h */