changeset 386:94ff750679a6

Implement sidlib_write_sid_header() function.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 01 Jan 2022 16:25:42 +0200
parents 1049033c6bbd
children 51d6e86aa196
files sidlib.c sidlib.h
diffstat 2 files changed, 73 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/sidlib.c	Sat Jan 01 16:25:17 2022 +0200
+++ b/sidlib.c	Sat Jan 01 16:25:42 2022 +0200
@@ -1207,3 +1207,74 @@
 
     return item != NULL ? *item : NULL;
 }
+
+
+int sidlib_write_sid_header(th_ioctx *ctx, const SIDLibPSIDHeader *psid)
+{
+    int ret = THERR_OK;
+    SIDLibPSIDHeader hsid;
+
+    if (psid->version < 1 || psid->version > 4)
+    {
+        ret = th_io_error(ctx, THERR_INVALID_DATA,
+            "Invalid or unsupported SID version %d",
+            psid->version);
+        goto exit;
+    }
+
+    if (psid->isRSID && psid->version < 2)
+    {
+        ret = th_io_error(ctx, THERR_INVALID_DATA,
+            "Invalid SID, RSID set, but version %d < 2?",
+            psid->version);
+        goto exit;
+    }
+
+    // Write header
+    hsid.magic[0] = psid->isRSID ? 'R' : 'P';
+    hsid.magic[1] = 'S';
+    hsid.magic[2] = 'I';
+    hsid.magic[3] = 'D';
+    hsid.dataOffset =
+        4 + 7*2 + 4 + 3*SIDLIB_PSID_STR_LEN;
+
+    if (psid->version >= 2)
+        hsid.dataOffset += 2 + 4*1;
+
+    if (!thfwrite_str(ctx, (uint8_t *) hsid.magic, SIDLIB_PSID_MAGIC_LEN) ||
+        !thfwrite_be16(ctx, psid->version) ||
+        !thfwrite_be16(ctx, hsid.dataOffset) ||
+        !thfwrite_be16(ctx, psid->loadAddress) ||
+        !thfwrite_be16(ctx, psid->initAddress) ||
+        !thfwrite_be16(ctx, psid->playAddress) ||
+        !thfwrite_be16(ctx, psid->nSongs) ||
+        !thfwrite_be16(ctx, psid->startSong) ||
+        !thfwrite_be32(ctx, psid->speed) ||
+        !thfwrite_str(ctx, psid->sidName, SIDLIB_PSID_STR_LEN) ||
+        !thfwrite_str(ctx, psid->sidAuthor, SIDLIB_PSID_STR_LEN) ||
+        !thfwrite_str(ctx, psid->sidReleased, SIDLIB_PSID_STR_LEN))
+    {
+        ret = th_io_error(ctx, ctx->status,
+            "Could not write PSID/RSID header.");
+        goto exit;
+    }
+
+    // Check if we need to load PSIDv2NG header ...
+    if (psid->version >= 2)
+    {
+        // Yes, we need to
+        if (!thfwrite_be16(ctx, psid->flags) ||
+            !thfwrite_u8(ctx, psid->startPage) ||
+            !thfwrite_u8(ctx, psid->pageLength) ||
+            !thfwrite_u8(ctx, psid->sid2Addr) ||
+            !thfwrite_u8(ctx, psid->sid3Addr))
+        {
+            ret = th_io_error(ctx, ctx->status,
+                "Error writing PSID/RSID v2+ extra header data.");
+            goto exit;
+        }
+    }
+
+exit:
+    return ret;
+}
--- a/sidlib.h	Sat Jan 01 16:25:17 2022 +0200
+++ b/sidlib.h	Sat Jan 01 16:25:42 2022 +0200
@@ -172,6 +172,8 @@
 int              sidlib_read_sid_file_alloc(th_ioctx *ctx, SIDLibPSIDHeader **ppsid, const BOOL newSLDB, SIDLibChConvCtx *chconv);
 void             sidlib_free_sid_file(SIDLibPSIDHeader *psid);
 
+int              sidlib_write_sid_header(th_ioctx *ctx, const SIDLibPSIDHeader *psid);
+
 const char *     sidlib_get_sid_clock_str(const int flags);
 const char *     sidlib_get_sid_model_str(const int flags);