changeset 70:4779bbec2f28

Split some functionality into sidlib.[ch].
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 01 Jan 2016 03:32:42 +0200
parents 19cbd8642875
children 1e6ad4be7f15
files Makefile.gen sidinfo.c sidlib.c sidlib.h
diffstat 4 files changed, 262 insertions(+), 232 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.gen	Fri Jan 01 03:17:11 2016 +0200
+++ b/Makefile.gen	Fri Jan 01 03:32:42 2016 +0200
@@ -13,7 +13,7 @@
 THLIBS_OBJ=th_util.o th_string.o th_endian.o th_args.o th_crypto.o
 
 
-SIDINFO_OBJ=sidinfo.o
+SIDINFO_OBJ=sidlib.o sidinfo.o
 SIDINFO_BIN=$(BINPATH)sidinfo$(EXEEXT)
 
 TARGETS += $(SIDINFO_BIN)
--- a/sidinfo.c	Fri Jan 01 03:17:11 2016 +0200
+++ b/sidinfo.c	Fri Jan 01 03:32:42 2016 +0200
@@ -1,12 +1,12 @@
 /*
  * SIDInfo - PSID/RSID information displayer
- * Written by Matti 'ccr' Hämäläinen
+ * Written by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
  * (C) Copyright 2014-2015 Tecnic Software productions (TNSP)
  */
 #include "th_args.h"
-#include "th_endian.h"
 #include "th_string.h"
-#include "th_crypto.h"
+#include "sidlib.h"
+
 
 // Some constants
 #define PSID_MAGIC_LEN    4
@@ -378,233 +378,6 @@
 }
 
 
-typedef struct
-{
-    char magic[PSID_MAGIC_LEN + 1]; // "PSID" / "RSID" magic identifier
-    uint16_t
-        version,         // Version number
-        dataOffset,      // Start of actual c64 data in file
-        loadAddress,     // Loading address
-        initAddress,     // Initialization address
-        playAddress,     // Play one frame
-        nSongs,          // Number of subsongs
-        startSong;       // Default starting song
-    uint32_t speed;      // Speed
-    char sidName[PSID_STR_LEN + 1];    // Descriptive text-fields, ASCIIZ
-    char sidAuthor[PSID_STR_LEN + 1];
-    char sidCopyright[PSID_STR_LEN + 1];
-
-    // PSIDv2 data
-    uint16_t flags;      // Flags
-    uint8_t  startPage, pageLength;
-    uint16_t reserved;
-
-    // Extra data
-    BOOL isRSID;
-    size_t dataSize;     // Total size of data - header
-    th_md5hash_t hash;   // Songlength database hash
-
-} PSIDHeader;
-
-
-enum
-{
-    PSF_PLAYER_TYPE   = 0x0001, // 0 = built-in, 1 = Compute! SIDPlayer MUS
-    PSF_PLAYSID_TUNE  = 0x0002, // 0 = Real C64-compatible, 1 = PlaySID specific (v2NG)
-
-    PSF_CLOCK_UNKNOWN = 0x0000, // Video standard used (v2NG)
-    PSF_CLOCK_PAL     = 0x0004,
-    PSF_CLOCK_NTSC    = 0x0008,
-    PSF_CLOCK_ANY     = 0x000c,
-    PSF_CLOCK_MASK    = 0x000c,
-
-    PSF_MODEL_UNKNOWN = 0x0000, // SID model (v2NG)
-    PSF_MODEL_MOS6581 = 0x0010,
-    PSF_MODEL_MOS8580 = 0x0020,
-    PSF_MODEL_ANY     = 0x0030,
-    PSF_MODEL_MASK    = 0x0030,
-};
-
-
-static void siAppendHash16(th_md5state_t *state, uint16_t data)
-{
-    uint8_t ib8[2];
-    ib8[0] = data & 0xff;
-    ib8[1] = data >> 8;
-    th_md5_append(state, (uint8_t *) &ib8, sizeof(ib8));
-}
-
-
-int siReadPSIDFile(FILE *inFile, PSIDHeader *psid)
-{
-    th_md5state_t state;
-    uint8_t tmp8, *fileData = NULL;
-    int index, ret = -1;
-    size_t read;
-    BOOL first;
-
-    memset(psid, 0, sizeof(*psid));
-
-    if ((fileData = (uint8_t *) th_malloc(PSID_BUFFER_SIZE)) == NULL)
-    {
-        THERR("Error allocating temporary data buffer of %d bytes.\n", PSID_BUFFER_SIZE);
-        goto error;
-    }
-
-    // Read PSID header in
-    if (!th_fread_str(inFile, (uint8_t *) psid->magic, PSID_MAGIC_LEN) ||
-        !th_fread_be16(inFile, &psid->version) ||
-        !th_fread_be16(inFile, &psid->dataOffset) ||
-        !th_fread_be16(inFile, &psid->loadAddress) ||
-        !th_fread_be16(inFile, &psid->initAddress) ||
-        !th_fread_be16(inFile, &psid->playAddress) ||
-        !th_fread_be16(inFile, &psid->nSongs) ||
-        !th_fread_be16(inFile, &psid->startSong) ||
-        !th_fread_be32(inFile, &psid->speed))
-    {
-        THERR("Could not read PSID/RSID header.\n");
-        goto error;
-    }
-
-    psid->magic[PSID_MAGIC_LEN] = 0;
-
-    if ((psid->magic[0] != 'R' && psid->magic[0] != 'P') ||
-        psid->magic[1] != 'S' || psid->magic[2] != 'I' || psid->magic[3] != 'D' ||
-        psid->version < 1 || psid->version > 3)
-    {
-        THERR("Not a supported PSID or RSID file.\n");
-        goto error;
-    }
-
-    psid->isRSID = psid->magic[0] == 'R';
-
-    if (!th_fread_str(inFile, (uint8_t *)psid->sidName, PSID_STR_LEN) ||
-        !th_fread_str(inFile, (uint8_t *)psid->sidAuthor, PSID_STR_LEN) ||
-        !th_fread_str(inFile, (uint8_t *)psid->sidCopyright, PSID_STR_LEN))
-    {
-        THERR("Error reading SID file header.\n");
-        goto error;
-    }
-
-    psid->sidName[PSID_STR_LEN] = 0;
-    psid->sidAuthor[PSID_STR_LEN] = 0;
-    psid->sidCopyright[PSID_STR_LEN] = 0;
-
-    // Check if we need to load PSIDv2NG header ...
-    if (psid->version >= 2)
-    {
-        // Yes, we need to
-        if (!th_fread_be16(inFile, &psid->flags) ||
-            !th_fread_byte(inFile, &psid->startPage) ||
-            !th_fread_byte(inFile, &psid->pageLength) ||
-            !th_fread_be16(inFile, &psid->reserved))
-        {
-            THERR("Error reading PSID/RSID v2+ extra header data.\n");
-            goto error;
-        }
-    }
-
-    // Initialize MD5-hash calculation
-    th_md5_init(&state);
-
-    // Process actual data
-    psid->dataSize = 0;
-    first = TRUE;
-    do
-    {
-        read = fread(fileData, sizeof(uint8_t), PSID_BUFFER_SIZE, inFile);
-        psid->dataSize += read;
-
-        if (first && psid->loadAddress == 0)
-        {
-            if (read < 4)
-            {
-                THERR("Error reading song data, unexpectedly small file.\n");
-                goto error;
-            }
-
-            // Grab the actual load address
-            psid->loadAddress = TH_LE16_TO_NATIVE(*(uint16_t *) fileData);
-
-            // Strip load address (2 first bytes)
-            th_md5_append(&state, &fileData[2], read - 2);
-            first = FALSE;
-        }
-        else
-        if (read > 0)
-        {
-            // Append "as is"
-            th_md5_append(&state, fileData, read);
-        }
-    } while (read > 0 && !feof(inFile));
-
-    // Append header data to hash
-    siAppendHash16(&state, psid->initAddress);
-    siAppendHash16(&state, psid->playAddress);
-    siAppendHash16(&state, psid->nSongs);
-
-    // Append song speed data to hash
-    tmp8 = psid->isRSID ? 60 : 0;
-    for (index = 0; index < psid->nSongs && index < 32; index++)
-    {
-        if (psid->isRSID)
-            tmp8 = 60;
-        else
-            tmp8 = (psid->speed & (1 << index)) ? 60 : 0;
-
-        th_md5_append(&state, &tmp8, sizeof(tmp8));
-    }
-
-    // Rest of songs (more than 32)
-    for (index = 32; index < psid->nSongs; index++)
-        th_md5_append(&state, &tmp8, sizeof(tmp8));
-
-    // PSIDv2NG specific
-    if (psid->version >= 2)
-    {
-        // REFER TO SIDPLAY HEADERS FOR MORE INFORMATION
-        tmp8 = (psid->flags >> 2) & 3;
-        if (tmp8 == 2)
-            th_md5_append(&state, &tmp8, sizeof(tmp8));
-    }
-
-    // Calculate the hash
-    th_md5_finish(&state, psid->hash);
-    ret = 0;
-
-error:
-    // Free buffer
-    th_free(fileData);
-    return ret;
-}
-
-
-const char *siGetSIDClockStr(int flags)
-{
-    switch (flags & PSF_CLOCK_MASK)
-    {
-        case PSF_CLOCK_UNKNOWN : return "Unknown";
-        case PSF_CLOCK_PAL     : return "PAL 50Hz";
-        case PSF_CLOCK_NTSC    : return "NTSC 60Hz";
-        case PSF_CLOCK_ANY     : return "PAL / NTSC";
-        default                : return "?";
-    }
-}
-
-
-const char *siGetSIDModelStr(int flags)
-{
-    switch (flags & PSF_MODEL_MASK)
-    {
-        case PSF_MODEL_UNKNOWN : return "Unknown";
-        case PSF_MODEL_MOS6581 : return "MOS6581";
-        case PSF_MODEL_MOS8580 : return "MOS8580";
-        case PSF_MODEL_ANY     : return "MOS6581 / MOS8580";
-        default                : return "?";
-    }
-}
-
-
 static void siPrintStrEscapes(FILE *outFile, const char *str)
 {
     while (*str)
@@ -777,7 +550,7 @@
 int main(int argc, char *argv[])
 {
     // Initialize
-    th_init("SIDInfo", "PSID/RSID information displayer", "0.6.0", NULL, NULL);
+    th_init("SIDInfo", "PSID/RSID information displayer", "0.6.1", NULL, NULL);
     th_verbosityLevel = 0;
 
     memset(&optFormat, 0, sizeof(optFormat));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sidlib.c	Fri Jan 01 03:32:42 2016 +0200
@@ -0,0 +1,186 @@
+/*
+ * SIDInfoLib - Way too simplistic PSID/RSID file library
+ * Written by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
+ * (C) Copyright 2014-2015 Tecnic Software productions (TNSP)
+ */
+#include "sidlib.h"
+#include "th_endian.h"
+
+
+static void siAppendHash16(th_md5state_t *state, uint16_t data)
+{
+    uint8_t ib8[2];
+    ib8[0] = data & 0xff;
+    ib8[1] = data >> 8;
+    th_md5_append(state, (uint8_t *) &ib8, sizeof(ib8));
+}
+
+
+int siReadPSIDFile(FILE *inFile, PSIDHeader *psid)
+{
+    th_md5state_t state;
+    uint8_t tmp8, *fileData = NULL;
+    int index, ret = -1;
+    size_t read;
+    BOOL first;
+
+    memset(psid, 0, sizeof(*psid));
+
+    if ((fileData = (uint8_t *) th_malloc(PSID_BUFFER_SIZE)) == NULL)
+    {
+        THERR("Error allocating temporary data buffer of %d bytes.\n", PSID_BUFFER_SIZE);
+        goto error;
+    }
+
+    // Read PSID header in
+    if (!th_fread_str(inFile, (uint8_t *) psid->magic, PSID_MAGIC_LEN) ||
+        !th_fread_be16(inFile, &psid->version) ||
+        !th_fread_be16(inFile, &psid->dataOffset) ||
+        !th_fread_be16(inFile, &psid->loadAddress) ||
+        !th_fread_be16(inFile, &psid->initAddress) ||
+        !th_fread_be16(inFile, &psid->playAddress) ||
+        !th_fread_be16(inFile, &psid->nSongs) ||
+        !th_fread_be16(inFile, &psid->startSong) ||
+        !th_fread_be32(inFile, &psid->speed))
+    {
+        THERR("Could not read PSID/RSID header.\n");
+        goto error;
+    }
+
+    psid->magic[PSID_MAGIC_LEN] = 0;
+
+    if ((psid->magic[0] != 'R' && psid->magic[0] != 'P') ||
+        psid->magic[1] != 'S' || psid->magic[2] != 'I' || psid->magic[3] != 'D' ||
+        psid->version < 1 || psid->version > 3)
+    {
+        THERR("Not a supported PSID or RSID file.\n");
+        goto error;
+    }
+
+    psid->isRSID = psid->magic[0] == 'R';
+
+    if (!th_fread_str(inFile, (uint8_t *)psid->sidName, PSID_STR_LEN) ||
+        !th_fread_str(inFile, (uint8_t *)psid->sidAuthor, PSID_STR_LEN) ||
+        !th_fread_str(inFile, (uint8_t *)psid->sidCopyright, PSID_STR_LEN))
+    {
+        THERR("Error reading SID file header.\n");
+        goto error;
+    }
+
+    psid->sidName[PSID_STR_LEN] = 0;
+    psid->sidAuthor[PSID_STR_LEN] = 0;
+    psid->sidCopyright[PSID_STR_LEN] = 0;
+
+    // Check if we need to load PSIDv2NG header ...
+    if (psid->version >= 2)
+    {
+        // Yes, we need to
+        if (!th_fread_be16(inFile, &psid->flags) ||
+            !th_fread_byte(inFile, &psid->startPage) ||
+            !th_fread_byte(inFile, &psid->pageLength) ||
+            !th_fread_be16(inFile, &psid->reserved))
+        {
+            THERR("Error reading PSID/RSID v2+ extra header data.\n");
+            goto error;
+        }
+    }
+
+    // Initialize MD5-hash calculation
+    th_md5_init(&state);
+
+    // Process actual data
+    psid->dataSize = 0;
+    first = TRUE;
+    do
+    {
+        read = fread(fileData, sizeof(uint8_t), PSID_BUFFER_SIZE, inFile);
+        psid->dataSize += read;
+
+        if (first && psid->loadAddress == 0)
+        {
+            if (read < 4)
+            {
+                THERR("Error reading song data, unexpectedly small file.\n");
+                goto error;
+            }
+
+            // Grab the actual load address
+            psid->loadAddress = TH_LE16_TO_NATIVE(*(uint16_t *) fileData);
+
+            // Strip load address (2 first bytes)
+            th_md5_append(&state, &fileData[2], read - 2);
+            first = FALSE;
+        }
+        else
+        if (read > 0)
+        {
+            // Append "as is"
+            th_md5_append(&state, fileData, read);
+        }
+    } while (read > 0 && !feof(inFile));
+
+    // Append header data to hash
+    siAppendHash16(&state, psid->initAddress);
+    siAppendHash16(&state, psid->playAddress);
+    siAppendHash16(&state, psid->nSongs);
+
+    // Append song speed data to hash
+    tmp8 = psid->isRSID ? 60 : 0;
+    for (index = 0; index < psid->nSongs && index < 32; index++)
+    {
+        if (psid->isRSID)
+            tmp8 = 60;
+        else
+            tmp8 = (psid->speed & (1 << index)) ? 60 : 0;
+
+        th_md5_append(&state, &tmp8, sizeof(tmp8));
+    }
+
+    // Rest of songs (more than 32)
+    for (index = 32; index < psid->nSongs; index++)
+        th_md5_append(&state, &tmp8, sizeof(tmp8));
+
+    // PSIDv2NG specific
+    if (psid->version >= 2)
+    {
+        // REFER TO SIDPLAY HEADERS FOR MORE INFORMATION
+        tmp8 = (psid->flags >> 2) & 3;
+        if (tmp8 == 2)
+            th_md5_append(&state, &tmp8, sizeof(tmp8));
+    }
+
+    // Calculate the hash
+    th_md5_finish(&state, psid->hash);
+    ret = 0;
+
+error:
+    // Free buffer
+    th_free(fileData);
+    return ret;
+}
+
+
+const char *siGetSIDClockStr(const int flags)
+{
+    switch (flags & PSF_CLOCK_MASK)
+    {
+        case PSF_CLOCK_UNKNOWN : return "Unknown";
+        case PSF_CLOCK_PAL     : return "PAL 50Hz";
+        case PSF_CLOCK_NTSC    : return "NTSC 60Hz";
+        case PSF_CLOCK_ANY     : return "PAL / NTSC";
+        default                : return "?";
+    }
+}
+
+
+const char *siGetSIDModelStr(const int flags)
+{
+    switch (flags & PSF_MODEL_MASK)
+    {
+        case PSF_MODEL_UNKNOWN : return "Unknown";
+        case PSF_MODEL_MOS6581 : return "MOS6581";
+        case PSF_MODEL_MOS8580 : return "MOS8580";
+        case PSF_MODEL_ANY     : return "MOS6581 / MOS8580";
+        default                : return "?";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sidlib.h	Fri Jan 01 03:32:42 2016 +0200
@@ -0,0 +1,71 @@
+/*
+ * SIDInfoLib - Way too simplistic PSID/RSID file library
+ * Written by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
+ * (C) Copyright 2014-2015 Tecnic Software productions (TNSP)
+ */
+#ifndef SIDLIB_H
+#define SIDLIB_H 1
+
+#include "th_util.h"
+#include "th_crypto.h"
+
+
+// Some constants
+#define PSID_MAGIC_LEN    4
+#define PSID_STR_LEN      32
+#define PSID_BUFFER_SIZE  (1024 * 16)
+
+
+typedef struct
+{
+    char magic[PSID_MAGIC_LEN + 1]; // "PSID" / "RSID" magic identifier
+    uint16_t
+        version,         // Version number
+        dataOffset,      // Start of actual c64 data in file
+        loadAddress,     // Loading address
+        initAddress,     // Initialization address
+        playAddress,     // Play one frame
+        nSongs,          // Number of subsongs
+        startSong;       // Default starting song
+    uint32_t speed;      // Speed
+    char sidName[PSID_STR_LEN + 1];    // Descriptive text-fields, ASCIIZ
+    char sidAuthor[PSID_STR_LEN + 1];
+    char sidCopyright[PSID_STR_LEN + 1];
+
+    // PSIDv2 data
+    uint16_t flags;      // Flags
+    uint8_t  startPage, pageLength;
+    uint16_t reserved;
+
+    // Extra data
+    BOOL isRSID;
+    size_t dataSize;     // Total size of data - header
+    th_md5hash_t hash;   // Songlength database hash
+
+} PSIDHeader;
+
+
+enum
+{
+    PSF_PLAYER_TYPE   = 0x0001, // 0 = built-in, 1 = Compute! SIDPlayer MUS
+    PSF_PLAYSID_TUNE  = 0x0002, // 0 = Real C64-compatible, 1 = PlaySID specific (v2NG)
+
+    PSF_CLOCK_UNKNOWN = 0x0000, // Video standard used (v2NG)
+    PSF_CLOCK_PAL     = 0x0004,
+    PSF_CLOCK_NTSC    = 0x0008,
+    PSF_CLOCK_ANY     = 0x000c,
+    PSF_CLOCK_MASK    = 0x000c,
+
+    PSF_MODEL_UNKNOWN = 0x0000, // SID model (v2NG)
+    PSF_MODEL_MOS6581 = 0x0010,
+    PSF_MODEL_MOS8580 = 0x0020,
+    PSF_MODEL_ANY     = 0x0030,
+    PSF_MODEL_MASK    = 0x0030,
+};
+
+int siReadPSIDFile(FILE *inFile, PSIDHeader *psid);
+const char *siGetSIDClockStr(const int flags);
+const char *siGetSIDModelStr(const int flags);
+
+
+#endif // SIDLIB_H