]> git.sesse.net Git - pistorm/blob - config_file/rominfo.c
Add Meson build files.
[pistorm] / config_file / rominfo.c
1 // SPDX-License-Identifier: MIT
2
3 #include <string.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdbool.h>
7 #include <inttypes.h>
8
9 #include "rominfo.h"
10
11 static void getDiagRom(uint8_t *address, struct romInfo *info)
12 {
13     uint8_t *ptr = address + 0xC8;
14     uint8_t data = *ptr;
15     char *endptr = NULL;
16     if (data != 0x56) // V
17     {
18         return;
19     }
20     ptr++;
21     info->major = strtoul((const char*)ptr, &endptr, 10);
22     if (!endptr)
23     {
24         return;
25     }
26     data = *endptr;
27     if (data != '.')
28     {
29         info->minor = 0;
30         return;
31     }
32     endptr++;
33     info->minor = strtoul(endptr, &endptr, 10);
34     if (!endptr)
35     {
36         return;
37     }
38     info->isDiagRom = true;
39     data = *endptr;
40     if (data != '.')
41     {
42         info->extra = 0;
43         return;
44     }
45     endptr++;
46     info->extra = strtoul(endptr, NULL, 10);
47 }
48
49 static void swapRom(uint8_t *address, size_t length)
50 {
51     uint8_t *ptr = address;
52     for (size_t pos = 0; pos < length; pos = pos + 2)
53     {
54         uint8_t low = ptr[pos];
55         uint8_t high = ptr[pos+1];
56         ptr[pos] = high;
57         ptr[pos+1] = low;
58     }
59 }
60
61 static void getRomInfo(uint8_t *address, size_t length, struct romInfo *info)
62 {
63     uint8_t *ptr = address;
64     uint8_t data = *ptr;
65     info->isDiagRom = false;
66
67     if ((ptr[2] == 0xF9) && (ptr[3] == 0x4E))
68     {
69         // ROM byte swapped!
70         printf("[CFG] Byte swapped ROM found, swapping back\n");
71         swapRom(address, length);
72         data = *ptr;
73     }
74
75     if (data != 0x11)
76     {
77         info->id = ROM_TYPE_UNKNOWN;
78
79         return;
80     }
81     ptr++;
82     data = *ptr;
83     switch (data)
84     {
85         case 0x11:
86             info->id = ROM_TYPE_256;
87             break;
88         case 0x14:
89         case 0x16: // kick40063.A600
90             info->id = ROM_TYPE_512;
91             break;
92         default:
93             info->id = ROM_TYPE_UNKNOWN;
94             return;
95             break;
96     }
97     ptr++;
98     data = *ptr;
99     if (data != 0x4E) // 256K byte swapped
100     {
101         return;
102     }
103     // This is wrong endian for us
104     uint16_t ver_read;
105     memcpy(&ver_read, address+12, 2);
106     info->major = (ver_read >> 8) | (ver_read << 8);
107     memcpy(&ver_read, address+14, 2);
108     info->minor = (ver_read >> 8) | (ver_read << 8);
109     // We hit part of a memory ptr for DiagROM, it will be > 200
110     if (info->major > 100)
111     {
112         getDiagRom(address, info);
113     }
114     return;
115 }
116
117 void displayRomInfo(uint8_t *address, size_t length)
118 {
119     struct romInfo info = {0};
120     const char *kversion;
121     const char *size;
122
123     getRomInfo(address, length, &info);
124
125     if ((!info.isDiagRom) && (info.id != ROM_TYPE_UNKNOWN))
126     {
127         switch(info.major)
128         {
129             case 27:
130                 kversion = "Kickstart 0.7";
131                 break;
132             case 30:
133                 kversion = "Kickstart 1.0";
134                 break;
135             case 31:
136                 kversion = "Kickstart 1.1";
137                 break;
138             case 33:
139                 kversion = "Kickstart 1.2";
140                 break;
141             case 34:
142                 kversion = "Kickstart 1.3";
143                 break;
144             case 36:
145                 {
146                     // 36.002 and 36.015 were 1.4
147                     // 36.028, 36.067, 36.141 and 36.143 were 2.0
148                     // 36.207 was 2.02
149                     if (info.minor < 20)
150                     {
151                         kversion = "Kickstart 1.4";
152                     }
153                     else if (info.minor < 200)
154                     {
155                         kversion = "Kickstart 2.0";
156                     }
157                     else
158                     {
159                         kversion = "Kickstart 2.02";
160                     }
161                     break;
162                 }
163             case 37:
164                 {
165                     // 37.074 and 37.092 were 2.03
166                     // 37.175 was 2.04
167                     // 37.210, 37.299, 37.300 and 37.350 were 2.05
168                     if (info.minor < 100)
169                     {
170                         kversion = "Kickstart 2.03";
171                     }
172                     else if (info.minor < 200)
173                     {
174                         kversion = "Kickstart 2.04";
175                     }
176                     else
177                     {
178                         kversion = "Kickstart 2.05";
179                     }
180                     break;
181                 }
182                 break;
183             case 39:
184                 kversion = "Kickstart 3.0";
185                 break;
186             case 40:
187                 kversion = "Kickstart 3.1";
188                 break;
189             case 45:
190                 kversion = "Kickstart 3.x";
191                 break;
192             case 46:
193                 kversion = "Kickstart 3.1.4";
194                 break;
195             case 47:
196                 kversion = "Kickstart 3.2";
197                 break;
198             default:
199                 kversion = "Unknown";
200                 break;
201         }
202     }
203     switch (info.id)
204     {
205         case ROM_TYPE_256:
206             size = "256KB";
207             break;
208         case ROM_TYPE_512:
209             size = "512KB";
210             break;
211         default:
212             size = "";
213             break;
214     }
215
216     if (info.isDiagRom)
217     {
218         printf("[CFG] ROM identified: DiagRom V%hu.%hu.%hu %s\n", info.major, info.minor, info.extra, size);
219     }
220     else if (info.id == ROM_TYPE_UNKNOWN)
221     {
222         printf("[CFG] ROM cannot be identified\n");
223     }
224     else
225     {
226         printf("[CFG] ROM identified: %s (%hu.%hu) %s\n", kversion, info.major, info.minor, size);
227     }
228 }