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
This commit is contained in:
AJR 2017-05-11 18:30:04 -04:00
parent 78ecf89a06
commit 16cbbd9103

View File

@ -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;