欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

romcmp.c

显示compatiblemodes的算法
C
第 1 页 / 共 2 页
字号:
/***************************************************************************

    romcmp.c

    ROM comparison utility program.

    Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
    Visit http://mamedev.org for licensing and usage restrictions.

***************************************************************************/

#include "unzip.h"
#include "osdepend.h"	/* for CLIB_DECL */
#include "osdcore.h"

#include <stdarg.h>
#ifdef macintosh
#	include "macromcmp.h"
#else
#ifndef _WIN32
#	include <dirent.h>
#	include <errno.h>
#else
#	include <windows.h>
#endif
#include <sys/stat.h>
#ifdef _MSC_VER
#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
#endif
#endif


#define MAX_FILES 100

#ifndef MAX_FILENAME_LEN
#define MAX_FILENAME_LEN 12	/* increase this if you are using a real OS... */
#endif

#ifndef PATH_DELIM
#define PATH_DELIM '/'
#endif


/* for unzip.c */
void CLIB_DECL logerror(const char *text,...)
{
}



/* compare modes when one file is twice as long as the other */
/* A = All file */
/* 12 = 1st half */
/* 22 = 2nd half */
/* E = Even bytes */
/* O = Odd bytes */
/* E1 = Even bytes 1st half */
/* O1 = Odd bytes 1st half */
/* E2 = Even bytes 2nd half */
/* O2 = Odd bytes 2nd half */
enum {	MODE_A,
		MODE_NIB1,MODE_NIB2,
		MODE_12, MODE_22,
		MODE_14, MODE_24, MODE_34, MODE_44,
		MODE_E, MODE_O,
		MODE_E12, MODE_O12, MODE_E22, MODE_O22,
		TOTAL_MODES };
const char *modenames[] =
{
	"          ",
	"[bits 0-3]",
	"[bits 4-7]",
	"[1/2]     ",
	"[2/2]     ",
	"[1/4]     ",
	"[2/4]     ",
	"[3/4]     ",
	"[4/4]     ",
	"[even]    ",
	"[odd]     ",
	"[even 1/2]",
	"[odd 1/2] ",
	"[even 2/2]",
	"[odd 2/2] ",
};

static void compatiblemodes(int mode,int *start,int *end)
{
	if (mode == MODE_A)
	{
		*start = MODE_A;
		*end = MODE_A;
	}
	if (mode >= MODE_NIB1 && mode <= MODE_NIB2)
	{
		*start = MODE_NIB1;
		*end = MODE_NIB2;
	}
	if (mode >= MODE_12 && mode <= MODE_22)
	{
		*start = MODE_12;
		*end = MODE_22;
	}
	if (mode >= MODE_14 && mode <= MODE_44)
	{
		*start = MODE_14;
		*end = MODE_44;
	}
	if (mode >= MODE_E && mode <= MODE_O)
	{
		*start = MODE_E;
		*end = MODE_O;
	}
	if (mode >= MODE_E12 && mode <= MODE_O22)
	{
		*start = MODE_E12;
		*end = MODE_O22;
	}
}

struct _fileinfo
{
	char name[MAX_FILENAME_LEN+1];
	int size;
	unsigned char *buf;	/* file is read in here */
	int listed;
};
typedef struct _fileinfo fileinfo;

fileinfo files[2][MAX_FILES];
float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES];


static void checkintegrity(const fileinfo *file,int side)
{
	int i;
	int mask0,mask1;
	int addrbit;

	if (file->buf == 0) return;

	/* check for bad data lines */
	mask0 = 0x0000;
	mask1 = 0xffff;

	for (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]);
		if (mask0 == 0xffff && mask1 == 0x0000) break;
	}

	if (mask0 != 0xffff || mask1 != 0x0000)
	{
		int fixedmask;
		int bits;


		fixedmask = (~mask0 | mask1) & 0xffff;

		if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff))
			bits = 8;
		else bits = 16;

		printf("%-23s %-23s FIXED BITS (",side ? "" : file->name,side ? file->name : "");
		for (i = 0;i < bits;i++)
		{
			if (~mask0 & 0x8000) printf("0");
			else if (mask1 & 0x8000) printf("1");
			else printf("x");

			mask0 <<= 1;
			mask1 <<= 1;
		}
		printf(")\n");

		/* if the file contains a fixed value, we don't need to do the other */
		/* validity checks */
		if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00)
			return;
	}


	addrbit = 1;
	mask0 = 0;
	while (addrbit <= file->size/2)
	{
		for (i = 0;i < file->size;i++)
		{
			if (file->buf[i] != file->buf[i ^ addrbit]) break;
		}

		if (i == file->size)
			mask0 |= addrbit;

		addrbit <<= 1;
	}

	if (mask0)
	{
		if (mask0 == file->size/2)
			printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n",side ? "" : file->name,side ? file->name : "");
		else
		{
			printf("%-23s %-23s BADADDR",side ? "" : file->name,side ? file->name : "");
			for (i = 0;i < 24;i++)
			{
				if (file->size <= (1<<(23-i))) printf(" ");
				else if (mask0 & 0x800000) printf("-");
				else printf("x");
				mask0 <<= 1;
			}
			printf("\n");
		}
		return;
	}

	mask0 = 0x000000;
	mask1 = file->size-1;
	for (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 != file->size-1 || mask1 != 0x00)
	{
		printf("%-23s %-23s ",side ? "" : file->name,side ? file->name : "");
		for (i = 0;i < 24;i++)
		{
			if (file->size <= (1<<(23-i))) printf(" ");
			else if (~mask0 & 0x800000) printf("1");
			else if (mask1 & 0x800000) printf("0");
			else printf("x");
			mask0 <<= 1;
			mask1 <<= 1;
		}
		printf(" = 0xFF\n");

		return;
	}


	mask0 = 0x000000;
	mask1 = file->size-1;
	for (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 != file->size-1 || mask1 != 0x00)
	{
		printf("%-23s %-23s ",side ? "" : file->name,side ? file->name : "");
		for (i = 0;i < 24;i++)
		{
			if (file->size <= (1<<(23-i))) printf(" ");
			else if ((mask0 & 0x800000) == 0) printf("1");
			else if (mask1 & 0x800000) printf("0");
			else printf("x");
			mask0 <<= 1;
			mask1 <<= 1;
		}
		printf(" = 0x00\n");

		return;
	}


	mask0 = 0xff;
	for (i = 0;i < file->size/4 && mask0;i++)
	{
		if (file->buf[               2*i  ] != 0x00) mask0 &= ~0x01;
		if (file->buf[               2*i  ] != 0xff) mask0 &= ~0x02;
		if (file->buf[               2*i+1] != 0x00) mask0 &= ~0x04;
		if (file->buf[               2*i+1] != 0xff) mask0 &= ~0x08;
		if (file->buf[file->size/2 + 2*i  ] != 0x00) mask0 &= ~0x10;
		if (file->buf[file->size/2 + 2*i  ] != 0xff) mask0 &= ~0x20;
		if (file->buf[file->size/2 + 2*i+1] != 0x00) mask0 &= ~0x40;
		if (file->buf[file->size/2 + 2*i+1] != 0xff) mask0 &= ~0x80;
	}

	if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n",side ? "" : file->name,side ? file->name : "");
	if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n",side ? "" : file->name,side ? file->name : "");
	if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n",side ? "" : file->name,side ? file->name : "");
	if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n",side ? "" : file->name,side ? file->name : "");
	if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n",side ? "" : file->name,side ? file->name : "");
	if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n",side ? "" : file->name,side ? file->name : "");
	if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n",side ? "" : file->name,side ? file->name : "");
	if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n",side ? "" : file->name,side ? file->name : "");
}


static int usedbytes(const fileinfo *file,int mode)
{
	switch (mode)
	{
		case MODE_A:
		case MODE_NIB1:
		case MODE_NIB2:
			return file->size;
		case MODE_12:
		case MODE_22:
		case MODE_E:
		case MODE_O:
			return file->size / 2;
		case MODE_14:
		case MODE_24:
		case MODE_34:
		case MODE_44:
		case MODE_E12:
		case MODE_O12:
		case MODE_E22:
		case MODE_O22:
			return file->size / 4;
		default:
			return 0;
	}
}

static void basemultmask(const fileinfo *file,int mode,int *base,int *mult,int *mask)
{
	*mult = 1;
	if (mode >= MODE_E) *mult = 2;

	switch (mode)
	{
		case MODE_A:
		case MODE_12:
		case MODE_14:
		case MODE_E:
		case MODE_E12:
			*base = 0; *mask = 0xff; break;
		case MODE_NIB1:
			*base = 0; *mask = 0x0f; break;
		case MODE_NIB2:
			*base = 0; *mask = 0xf0; break;
		case MODE_O:
		case MODE_O12:
			*base = 1; *mask = 0xff; break;
		case MODE_22:
		case MODE_E22:
			*base = file->size / 2; *mask = 0xff; break;
		case MODE_O22:
			*base = 1 + file->size / 2; *mask = 0xff; break;
		case MODE_24:
			*base = file->size / 4; *mask = 0xff; break;
		case MODE_34:
			*base = 2*file->size / 4; *mask = 0xff; break;
		case MODE_44:
			*base = 3*file->size / 4; *mask = 0xff; break;
	}
}

static float filecompare(const fileinfo *file1,const fileinfo *file2,int mode1,int mode2)
{
	int i;
	int match = 0;
	int size1,size2;
	int base1,base2,mult1,mult2,mask1,mask2;


	if (file1->buf == 0 || file2->buf == 0) return 0.0;

	size1 = usedbytes(file1,mode1);
	size2 = usedbytes(file2,mode2);

	if (size1 != size2) return 0.0;

	basemultmask(file1,mode1,&base1,&mult1,&mask1);
	basemultmask(file2,mode2,&base2,&mult2,&mask2);

	if (mask1 == mask2)
	{
		if (mask1 == 0xff)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -