summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools/romcmp.cpp
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2017-05-11 18:30:04 -0400
committer AJR <ajrhacker@users.noreply.github.com>2017-05-11 18:38:39 -0400
commit16cbbd91031df43437ee393cfd18ebc6373409eb (patch)
tree9aba1ee01a3e5e690c8a46184c1e8d1594334ee4 /src/tools/romcmp.cpp
parent78ecf89a06bcd864e703aec65344c1cfa9ffa879 (diff)
Improvements to romcmp
- Identify plain ASCII text files as such - If a ROM has the same data in each half, print the hashes for that - Avoid buffer overruns - For calculating address masks, don't assume file size to be a power of 2
Diffstat (limited to 'src/tools/romcmp.cpp')
-rw-r--r--src/tools/romcmp.cpp95
1 files changed, 60 insertions, 35 deletions
diff --git a/src/tools/romcmp.cpp b/src/tools/romcmp.cpp
index f45ff7f6eeb..8341353c029 100644
--- a/src/tools/romcmp.cpp
+++ b/src/tools/romcmp.cpp
@@ -11,6 +11,7 @@
#include "unzip.h"
#include "osdcore.h"
#include "osdcomm.h"
+#include "hash.h"
#include <stdarg.h>
#include <stdlib.h>
@@ -114,31 +115,45 @@ static fileinfo files[2][MAX_FILES];
static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES];
-static void checkintegrity(const fileinfo *file,int side)
+static bool is_ascii_char(int ch)
{
- int i;
- int mask0,mask1;
- int addrbit;
+ return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t');
+}
+static void checkintegrity(const fileinfo *file, int side)
+{
if (file->buf == nullptr) return;
/* check for bad data lines */
- mask0 = 0x0000;
- mask1 = 0xffff;
+ unsigned mask0 = 0x0000;
+ unsigned mask1 = 0xffff;
- for (i = 0;i < file->size;i+=2)
+ bool is_ascii = true;
+ for (unsigned i = 0; i < file->size; i += 2)
{
- mask0 |= ((file->buf[i] << 8) | file->buf[i+1]);
- mask1 &= ((file->buf[i] << 8) | file->buf[i+1]);
+ is_ascii = is_ascii && is_ascii_char(file->buf[i]);
+ mask0 |= file->buf[i] << 8;
+ mask1 &= file->buf[i] << 8;
+ if (i < file->size - 1)
+ {
+ is_ascii = is_ascii && is_ascii_char(file->buf[i+1]);
+ mask0 |= file->buf[i+1];
+ mask1 &= file->buf[i+1];
+ }
if (mask0 == 0xffff && mask1 == 0x0000) break;
}
+ if (is_ascii && mask0 == 0x7f7f && mask1 == 0)
+ {
+ printf("%-23s %-23s ASCII TEXT FILE\n", side ? "" : file->name, side ? file->name : "");
+ return;
+ }
+
if (mask0 != 0xffff || mask1 != 0x0000)
{
int fixedmask;
int bits;
-
fixedmask = (~mask0 | mask1) & 0xffff;
if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff))
@@ -146,7 +161,7 @@ static void checkintegrity(const fileinfo *file,int side)
else bits = 16;
printf("%-23s %-23s FIXED BITS (",side ? "" : file->name,side ? file->name : "");
- for (i = 0;i < bits;i++)
+ for (int i = 0; i < bits; i++)
{
if (~mask0 & 0x8000) printf("0");
else if (mask1 & 0x8000) printf("1");
@@ -163,57 +178,68 @@ static void checkintegrity(const fileinfo *file,int side)
return;
}
-
- addrbit = 1;
- mask0 = 0;
+ unsigned addrbit = 1;
+ unsigned addrmirror = 0;
while (addrbit <= file->size/2)
{
- for (i = 0;i < file->size;i++)
+ unsigned i = 0;
+ for (i = 0; i < file->size; i++)
{
- if (file->buf[i] != file->buf[i ^ addrbit]) break;
+ if ((i ^ addrbit) < file->size && file->buf[i] != file->buf[i ^ addrbit]) break;
}
if (i == file->size)
- mask0 |= addrbit;
+ addrmirror |= addrbit;
addrbit <<= 1;
}
- if (mask0)
+ if (addrmirror != 0)
{
- if (mask0 == file->size/2)
- printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n",side ? "" : file->name,side ? file->name : "");
+ if (addrmirror == file->size/2)
+ {
+ printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", side ? "" : file->name, side ? file->name : "");
+ util::hash_collection hash;
+ hash.begin();
+ hash.buffer(file->buf, file->size / 2);
+ hash.end();
+ printf("%-23s %-23s %s\n", side ? "" : file->name, side ? file->name : "", hash.attribute_string().c_str());
+ }
else
{
printf("%-23s %-23s BADADDR",side ? "" : file->name,side ? file->name : "");
- for (i = 0;i < 24;i++)
+ for (int i = 0; i < 24; i++)
{
if (file->size <= (1<<(23-i))) printf(" ");
- else if (mask0 & 0x800000) printf("-");
+ else if (addrmirror & 0x800000) printf("-");
else printf("x");
- mask0 <<= 1;
+ addrmirror <<= 1;
}
printf("\n");
}
return;
}
+ unsigned sizemask = 1;
+ while (sizemask < file->size - 1)
+ sizemask = (sizemask << 1) | 1;
+
mask0 = 0x000000;
- mask1 = file->size-1;
- for (i = 0;i < file->size;i++)
+ mask1 = sizemask;
+ for (unsigned i = 0; i < file->size; i++)
{
if (file->buf[i] != 0xff)
{
mask0 |= i;
mask1 &= i;
- if (mask0 == file->size-1 && mask1 == 0x00) break;
+ if (mask0 == sizemask && mask1 == 0x00) break;
}
}
- if (mask0 != file->size-1 || mask1 != 0x00)
+ if (mask0 != sizemask || mask1 != 0x00)
{
printf("%-23s %-23s ",side ? "" : file->name,side ? file->name : "");
- for (i = 0;i < 24;i++)
+ for (int i = 0; i < 24; i++)
{
if (file->size <= (1<<(23-i))) printf(" ");
else if (~mask0 & 0x800000) printf("1");
@@ -229,21 +255,21 @@ static void checkintegrity(const fileinfo *file,int side)
mask0 = 0x000000;
- mask1 = file->size-1;
- for (i = 0;i < file->size;i++)
+ mask1 = sizemask;
+ for (unsigned i = 0; i < file->size; i++)
{
if (file->buf[i] != 0x00)
{
mask0 |= i;
mask1 &= i;
- if (mask0 == file->size-1 && mask1 == 0x00) break;
+ if (mask0 == sizemask && mask1 == 0x00) break;
}
}
- if (mask0 != file->size-1 || mask1 != 0x00)
+ if (mask0 != sizemask || mask1 != 0x00)
{
printf("%-23s %-23s ",side ? "" : file->name,side ? file->name : "");
- for (i = 0;i < 24;i++)
+ for (int i = 0; i < 24; i++)
{
if (file->size <= (1<<(23-i))) printf(" ");
else if ((mask0 & 0x800000) == 0) printf("1");
@@ -257,9 +283,8 @@ static void checkintegrity(const fileinfo *file,int side)
return;
}
-
mask0 = 0xff;
- for (i = 0;i < file->size/4 && mask0;i++)
+ for (unsigned i = 0; i < file->size/4 && mask0 != 0x00; i++)
{
if (file->buf[ 2*i ] != 0x00) mask0 &= ~0x01;
if (file->buf[ 2*i ] != 0xff) mask0 &= ~0x02;