if (Global::a2rSize > (60 + Uint32LE(Global::a2r->strmSize)))
{
- Global::metadata = (A2RMetadata *)((uint8_t *)Global::a2r + (60 + Uint32LE(Global::a2r->strmSize)));
+ Global::metadata = (Metadata *)((uint8_t *)Global::a2r + (60 + Uint32LE(Global::a2r->strmSize)));
// Make sure it's plausible metadata
if (memcmp(Global::metadata->metaTag, "META", 4) != 0)
Global::metadata = NULL;
+ else
+ UnpackMetadata(Global::metadata);
}
// Unpack TMNG & XTMG streams to simplify analysis
return true;
}
+
+void UnpackMetadata(Metadata * data)
+{
+ uint32_t start = 0;
+ uint32_t end = Uint32LE(data->metaSize);
+ uint32_t i = 0;
+ Global::metaCount = 0;
+
+ while (start < end)
+ {
+ if (i < 255)
+ Global::meta[Global::metaCount][i++] = data->data[start];
+
+ start++;
+
+ if (data->data[start] == '\x0A')
+ {
+ Global::meta[Global::metaCount][i] = 0;
+ Global::metaCount++;
+ i = 0;
+ start++;
+ }
+ }
+}
+
+
+uint8_t * GetMetadata(const char * keyword)
+{
+ uint32_t kwLen = strlen(keyword);
+
+ for(uint8_t i=0; i<Global::metaCount; i++)
+ {
+ if ((strlen((char *)Global::meta[i]) >= kwLen)
+ && (memcmp(Global::meta[i], keyword, kwLen) == 0))
+ {
+ return &Global::meta[i][kwLen];
+ }
+ }
+
+ return NULL;
+}
+
+
+uint16_t GetRequiredMachineBits(void)
+{
+ uint8_t * kw = GetMetadata("requires_machine\x09");
+ uint32_t kwLen = strlen((char *)kw);
+ uint16_t bits = 0;
+ char type[8];
+ uint8_t typeLen = 0;
+
+ for(uint32_t i=0; i<kwLen; i++)
+ {
+ type[typeLen++] = kw[i];
+
+ if ((kw[i + 1] == '|') || (kw[i + 1] == '\0'))
+ {
+ type[typeLen] = 0;
+
+ if (strcmp(type, "2") == 0)
+ bits |= 0x001;
+ else if (strcmp(type, "2+") == 0)
+ bits |= 0x002;
+ else if (strcmp(type, "2e") == 0)
+ bits |= 0x004;
+ else if (strcmp(type, "2c") == 0)
+ bits |= 0x008;
+ else if (strcmp(type, "2e+") == 0)
+ bits |= 0x010;
+ else if (strcmp(type, "2gs") == 0)
+ bits |= 0x020;
+ else if (strcmp(type, "2c+") == 0)
+ bits |= 0x040;
+ else if (strcmp(type, "3") == 0)
+ bits |= 0x080;
+ else if (strcmp(type, "3+") == 0)
+ bits |= 0x100;
+
+ typeLen = 0;
+ i++;
+ }
+ }
+
+ return bits;
+}
+
+
+uint16_t GetRequiredRAMInK(void)
+{
+ char * kw = (char *)GetMetadata("requires_ram\x09");
+
+ if (strcmp(kw, "16K") == 0)
+ return 16;
+ else if (strcmp(kw, "24K") == 0)
+ return 24;
+ else if (strcmp(kw, "32K") == 0)
+ return 32;
+ else if (strcmp(kw, "48K") == 0)
+ return 48;
+ else if (strcmp(kw, "64K") == 0)
+ return 64;
+ else if (strcmp(kw, "128K") == 0)
+ return 128;
+ else if (strcmp(kw, "256K") == 0)
+ return 256;
+ else if (strcmp(kw, "512K") == 0)
+ return 512;
+ else if (strcmp(kw, "768K") == 0)
+ return 768;
+ else if (strcmp(kw, "1M") == 0)
+ return 1024;
+ else if (strcmp(kw, "1.25M") == 0)
+ return 1280;
+ else if (strcmp(kw, "1.5M+") == 0)
+ return 1536;
+
+ return 0;
+}
+/*
+METADATA Keywords (standard)
+----------------------------
+title, subtitle, publisher, developer, copyright, version, language, requires_ram, requires_machine, notes, side, side_name, contributor, image_date
+
+ram: 16K|24K|32K|48K|64K|128K|256K|512K|768K|1M|1.25M|1.5M+|Unknown
+mch: 2|2+|2e|2c|2e+|2gs|2c+|3|3+
+*/
+