]> git.sur5r.net Git - cc65/blobdiff - src/ld65/xex.c
Add support for INITAD to the Atari binary format.
[cc65] / src / ld65 / xex.c
index 18190c063641e4f1c036afa69b8d942b69a625d8..e7674949a01910786f8424c959bff199b7ab50a0 100644 (file)
 /*                                   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,7 +120,34 @@ 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)),
@@ -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 */