]> git.sur5r.net Git - cc65/commitdiff
Only write full ATARI XEX header in the first chunk.
authorDaniel Serpell <daniel.serpell@gmail.com>
Tue, 25 Sep 2018 23:21:49 +0000 (20:21 -0300)
committerDaniel Serpell <daniel.serpell@gmail.com>
Sun, 3 Feb 2019 21:09:51 +0000 (18:09 -0300)
src/ld65/config.c
src/ld65/scanner.h
src/ld65/xex.c
src/ld65/xex.h

index fdf7d13eb7da070124eae38ff8eb855352bb867f..fafbed290bf06c18cb4d9a5b57ebc9c212d8ab1f 100644 (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)
 /* 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;
 
index 783685951ddbd77ee34f97a1da9d93316a44becd..77fa91da81a3031a2b54f61d04d6dd3e2d070f57 100644 (file)
@@ -93,6 +93,7 @@ typedef enum {
     CFGTOK_ID,
     CFGTOK_VERSION,
     CFGTOK_FORMAT,
+    CFGTOK_RUNAD,
 
     CFGTOK_LOAD,
     CFGTOK_RUN,
index 71065ea5755f26c742b63b2ac4f560f83cc7b521..9d373fb36324517ebc5e9839ffb69c604eef7e91 100644 (file)
@@ -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));
index fd6ba7201489b44c12c04f0ffad55286795f6d74..c74f78eca3bf768019a0573c5e9277c98a425646 100644 (file)
@@ -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 */