]> git.sesse.net Git - pistorm/commitdiff
Add ROM identification code
authorAndrew Hutchings <andrew@linuxjedi.co.uk>
Sat, 24 Apr 2021 14:48:20 +0000 (15:48 +0100)
committerAndrew Hutchings <andrew@linuxjedi.co.uk>
Sat, 24 Apr 2021 14:48:20 +0000 (15:48 +0100)
Ported over my ROM identification code, mostly to identify when you are
using a ROM that won't boot and log it. But also cool to log which ROM
is booting if we need to help a user.

Makefile
config_file/config_file.c
config_file/rominfo.c [new file with mode: 0644]
config_file/rominfo.h [new file with mode: 0644]

index 5e193202ec5917371da2b7bd0bd1f5b2abc7cf8a..4772a1b3e4e8f101f1776a3c5a83733a9546f416 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@ EXENAME          = emulator
 MAINFILES        = emulator.c \
        memory_mapped.c \
        config_file/config_file.c \
+       config_file/rominfo.c \
        input/input.c \
        gpio/ps_protocol.c \
        platforms/platforms.c \
index 85a5a2097ab7049cf4945f7e7a774c87596188c6..dec1554c31de945a244995b751909558744f273e 100644 (file)
@@ -5,6 +5,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "rominfo.h"
+
 #define M68K_CPU_TYPES M68K_CPU_TYPE_SCC68070
 
 const char *cpu_types[M68K_CPU_TYPES] = {
@@ -227,6 +229,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
       memset(cfg->map_data[index], 0x00, cfg->map_size[index]);
       fread(cfg->map_data[index], cfg->rom_size[index], 1, in);
       fclose(in);
+      displayRomInfo(cfg->map_data[index]);
       break;
     case MAPTYPE_REGISTER:
     default:
diff --git a/config_file/rominfo.c b/config_file/rominfo.c
new file mode 100644 (file)
index 0000000..d264db6
--- /dev/null
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: MIT
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include "rominfo.h"
+
+static void getDiagRom(uint8_t *address, struct romInfo *info)
+{
+    uint8_t *ptr = address + 0xC8;
+    uint8_t data = *ptr;
+    char *endptr = NULL;
+    if (data != 0x56) // V
+    {
+        return;
+    }
+    ptr++;
+    info->major = strtoul((const char*)ptr, &endptr, 10);
+    if (!endptr)
+    {
+        return;
+    }
+    data = *endptr;
+    if (data != '.')
+    {
+        info->minor = 0;
+        return;
+    }
+    endptr++;
+    info->minor = strtoul(endptr, &endptr, 10);
+    if (!endptr)
+    {
+        return;
+    }
+    info->isDiagRom = true;
+    data = *endptr;
+    if (data != '.')
+    {
+        info->extra = 0;
+        return;
+    }
+    endptr++;
+    info->extra = strtoul(endptr, NULL, 10);
+}
+
+static void getRomInfo(uint8_t *address, struct romInfo *info)
+{
+    uint8_t *ptr = address;
+    uint8_t data = *ptr;
+    info->isDiagRom = false;
+
+    if (data != 0x11)
+    {
+        info->id = ROM_TYPE_UNKNOWN;
+
+        return;
+    }
+    ptr++;
+    data = *ptr;
+    switch (data)
+    {
+        case 0x11:
+            info->id = ROM_TYPE_256;
+            break;
+        case 0x14:
+        case 0x16: // kick40063.A600
+            info->id = ROM_TYPE_512;
+            break;
+        default:
+            info->id = ROM_TYPE_UNKNOWN;
+            return;
+            break;
+    }
+    ptr++;
+    data = *ptr;
+    if (data != 0x4E) // 256K byte swapped
+    {
+        return;
+    }
+    // This is wrong endian for us
+    uint16_t ver_read;
+    memcpy(&ver_read, address+12, 2);
+    info->major = (ver_read >> 8) | (ver_read << 8);
+    memcpy(&ver_read, address+14, 2);
+    info->minor = (ver_read >> 8) | (ver_read << 8);
+    // We hit part of a memory ptr for DiagROM, it will be > 200
+    if (info->major > 100)
+    {
+        getDiagRom(address, info);
+    }
+    return;
+}
+
+void displayRomInfo(uint8_t *address)
+{
+    struct romInfo info = {0};
+    const char *kversion;
+    const char *size;
+
+    getRomInfo(address, &info);
+
+    if ((!info.isDiagRom) && (info.id != ROM_TYPE_UNKNOWN))
+    {
+        switch(info.major)
+        {
+            case 27:
+                kversion = "Kickstart 0.7";
+                break;
+            case 30:
+                kversion = "Kickstart 1.0";
+                break;
+            case 31:
+                kversion = "Kickstart 1.1";
+                break;
+            case 33:
+                kversion = "Kickstart 1.2";
+                break;
+            case 34:
+                kversion = "Kickstart 1.3";
+                break;
+            case 36:
+                {
+                    // 36.002 and 36.015 were 1.4
+                    // 36.028, 36.067, 36.141 and 36.143 were 2.0
+                    // 36.207 was 2.02
+                    if (info.minor < 20)
+                    {
+                        kversion = "Kickstart 1.4";
+                    }
+                    else if (info.minor < 200)
+                    {
+                        kversion = "Kickstart 2.0";
+                    }
+                    else
+                    {
+                        kversion = "Kickstart 2.02";
+                    }
+                    break;
+                }
+            case 37:
+                {
+                    // 37.074 and 37.092 were 2.03
+                    // 37.175 was 2.04
+                    // 37.210, 37.299, 37.300 and 37.350 were 2.05
+                    if (info.minor < 100)
+                    {
+                        kversion = "Kickstart 2.03";
+                    }
+                    else if (info.minor < 200)
+                    {
+                        kversion = "Kickstart 2.04";
+                    }
+                    else
+                    {
+                        kversion = "Kickstart 2.05";
+                    }
+                    break;
+                }
+                break;
+            case 39:
+                kversion = "Kickstart 3.0";
+                break;
+            case 40:
+                kversion = "Kickstart 3.1";
+                break;
+            case 45:
+                kversion = "Kickstart 3.x";
+                break;
+            case 46:
+                kversion = "Kickstart 3.1.4";
+                break;
+            default:
+                kversion = "Unknown";
+                break;
+        }
+    }
+    switch (info.id)
+    {
+        case ROM_TYPE_256:
+            size = "256KB";
+            break;
+        case ROM_TYPE_512:
+            size = "512KB";
+            break;
+        default:
+            size = "";
+            break;
+    }
+
+    if (info.isDiagRom)
+    {
+        printf("[CFG] ROM identified: DiagRom V%hu.%hu.%hu %s\n", info.major, info.minor, info.extra, size);
+    }
+    else if (info.id == ROM_TYPE_UNKNOWN)
+    {
+        printf("[CFG] ROM cannot be identified, if it is a byte swapped Kickstart this will fail\n");
+    }
+    else
+    {
+        printf("[CFG] ROM identified: %s (%hu.%hu) %s\n", kversion, info.major, info.minor, size);
+    }
+}
diff --git a/config_file/rominfo.h b/config_file/rominfo.h
new file mode 100644 (file)
index 0000000..0c43f2f
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MIT
+
+#ifndef __ROMINFO__
+#define __ROMINFO__
+
+#include <stdbool.h>
+#include <inttypes.h>
+
+enum romType {
+    ROM_TYPE_UNKNOWN,
+    ROM_TYPE_256,
+    ROM_TYPE_512,
+};
+
+struct romInfo {
+    enum romType id;
+    uint16_t major;
+    uint16_t minor;
+    uint16_t extra;
+    bool isDiagRom;
+};
+
+enum romErrCode {
+    ERR_NO_ERR,
+    ERR_NOT_ROM,
+    ERR_ROM_UNKNOWN
+};
+
+void displayRomInfo(uint8_t *address);
+#endif /* __ROMINFO */