Revision 66d8e606a8d996ded60bc81d5edf319142a5fad9 authored by Ron Burkey on 04 October 2021, 11:49:55 UTC, committed by Ron Burkey on 04 October 2021, 11:49:55 UTC
bdiffhead.c
/*
* Copyright 2004,2016 Ronald S. Burkey <info@sandroid.org>
*
* This file is part of yaAGC.
*
* yaAGC is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* yaAGC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with yaAGC; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Filename: bdiffhead.c
* Purpose: For the purpose of debugging yaYUL and the Luminary source
* code, I need some way to do meaningful binary comparisons
* of two core-rope files and getting some meaningful list
* of their differences. (The 'diff' utility can tell me that
* the files are identical or different, but does not tell
* me HOW they differ, as far as I can determine. The 'xdelta'
* utility goes much farther but, again, rather than telling me
* in some simple why what's different, it gives me back an
* unreadable patch-file. The DOS/Win32 utility fc does what
* I want, more or less, but I don't want to fire up Win32 just
* for this purpose.)
* Mode: 07/26/04 RSB Wrote.
* 08/21/16 RSB Adapted for Block 1.
* 10/20/16 RSB Somehow the --no-super option got messed up.
* Also, introduced --no-super2.
* 11/02/16 RSB Added the case of 0 to --no-super.
* 02/01/17 MAS Added display of parity if its presence is
* detected.
*
* The idea is simple. We just do a word-by-word compare until we run out of
* data, and print messages where the words differ. Originally I intended to
* limit this to just the first N (configurable) lines of output, but now I
* just do the complete files and feed the results into 'head' if I don't want
* to see the whole thing.
*
* Since this is tailored to core-rope comparisons, the data consists of 16-bit
* words and the messages use core-rope addresses rather than absolute offsets
* into the file.
*/
#include <stdio.h>
#include <string.h>
#define CORE_LENGTH_BLOCK2 (2 * 044 * 02000)
#define CORE_LENGTH_BLOCK1 (2 * 034 * 02000)
int
main(int argc, char *argv[])
{
FILE *f1, *f2;
int n1, n2, i, NoSuper = 0, NoSuper2 = 0, NoZero = 0, OnlySuper = 0, Block1 =
0;
unsigned char d1[2], d2[2];
// Parse command-line arguments.
if (argc < 3)
{
printf("USAGE:\n"
"\tbdiffhead AgcCoreFilename1 AgcCoreFilename2 [OPTIONS]\n"
"A binary-compare of two files is performed, and a list of all\n"
"differences is printed. The files are supposed to represent\n"
"AGC (Apollo Guidance Computer) core-ropes, consisting of 16-bit\n"
"words. The output messages use the AGC addressing scheme.\n"
"The available options are:\n"
"--no-super This option discards differences in which one\n"
" word has 100 (binary) in bit-positions 5,6,7\n"
" (the least-significant bit being position 1)\n"
" and 011 in the other word.\n"
"--only-super The opposite of the --no-super option. Shows\n"
" ONLY differences involving 000 vs. 100 vs. 011 in \n"
" bits 5,6,7.\n"
"--no-super2 Similar to --no-super, but discards ALL \n"
" differences which are merely in bit 7.\n"
"--no-zero This option discards differences in which the\n"
" word from the 2nd file is 00000.\n");
return (1);
}
f1 = fopen(argv[1], "rb");
if (f1 == NULL)
{
printf("Could not open file \"%s\".\n", argv[1]);
return (1);
}
f2 = fopen(argv[2], "rb");
if (f2 == NULL)
{
fclose(f1);
printf("Could not open file \"%s\".\n", argv[2]);
return (2);
}
for (n1 = 3; n1 < argc; n1++)
{
if (!strcmp(argv[n1], "--no-super"))
NoSuper = 1;
else if (!strcmp(argv[n1], "--no-super2"))
NoSuper2 = 1;
else if (!strcmp(argv[n1], "--only-super"))
OnlySuper = 1;
else if (!strcmp(argv[n1], "--no-zero"))
NoZero = 1;
else
printf("Unrecognized option \"%s\".\n", argv[n1]);
}
// See if the files are the same length.
fseek(f1, 0, SEEK_END);
fseek(f2, 0, SEEK_END);
n1 = ftell(f1);
n2 = ftell(f2);
rewind(f1);
rewind(f2);
if (n1 == CORE_LENGTH_BLOCK1)
{
Block1 = 1;
printf("File %s is Block 1.\n", argv[1]);
}
else if (n1 == CORE_LENGTH_BLOCK2)
printf("File %s is Block 2.\n", argv[1]);
else
printf("File %s is neither Block 1 nor Block 2.\n", argv[1]);
if (n2 == CORE_LENGTH_BLOCK1)
{
Block1 = 1;
printf("File %s is Block 1.\n", argv[2]);
}
else if (n2 == CORE_LENGTH_BLOCK2)
printf("File %s is Block 2.\n", argv[2]);
else
printf("File %s is neither Block 1 nor Block 2.\n", argv[2]);
if (n1 != n2)
printf("Files %s and %s are not the same length.\n", argv[1], argv[2]);
if (n1 < n2)
n2 = n1;
else if (n2 < n1)
n1 = n2;
// Now compare!
while (1 == fread(d1, 2, 1, f1) && 1 == fread(d2, 2, 1, f2))
if (d1[0] != d2[0] || d1[1] != d2[1])
{
int Bank, Offset;
n1 = (d1[0] << 7) | (d1[1] >> 1);
n2 = (d2[0] << 7) | (d2[1] >> 1);
if (NoZero && n2 == 0)
continue;
i = (ftell(f1) - 2) / 2;
if (Block1)
{
Offset = 06000 + (i % 02000);
Bank = 1 + i / 02000;
}
else
{
int sub1, sub2;
sub1 = 0160 & n1;
sub2 = 0160 & n2;
if (NoSuper2 && 00100 == (n1 ^ n2))
{
continue;
}
else if ((~0160 & n1) == (~0160 & n2) && sub1 != sub2
&& (((0100 == sub1 || 0060 == sub1 || 0000 == sub1)
&& (0100 == sub2 || 0060 == sub2 || 0000 == sub2))
|| ((0100 == sub1 || 0060 == sub1 || 0160 == sub1)
&& (0100 == sub2 || 0060 == sub2 || 0160 == sub2))))
{
if (NoSuper)
continue;
}
else
{
if (OnlySuper)
continue;
}
Offset = 02000 + (i % 02000);
Bank = i / 02000;
if (Bank < 4)
Bank ^= 2; // Swap banks 0,1 and 2,3.
}
printf("0%06o (%02o,%04o", i, Bank, Offset);
if (i < 04000)
printf(" or %04o): ", i + (Block1 ? 02000 : 04000));
else
printf("): ");
if ((d1[1] & 1) || (d2[1] & 1))
printf("%05o %o %05o %o\n", n1, d1[1] & 1, n2, d2[1] & 1);
else
printf("%05o %05o\n", n1, n2);
}
// All done!
return (0);
}
Computing file changes ...