BuildROMs enhancements.

- Added support to allow proper building of ROM dependent modules if the ROM image file is missing but the desired ROM image include file exists and has the correct/expected contents.
- Added support to help new ROMs to be added to the set of ROMs which are translated/tested.
- Added command Usage to program which is displayed if invoked with /? or /help  Usage displays the current set of ROM images which are known.
This commit is contained in:
Mark Pizzolato 2012-05-12 13:49:47 -07:00
parent 22b0e564a2
commit b816a42177

View file

@ -23,26 +23,30 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
- */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
/*
This program builds C include files which can be used to contain the contents This program builds C include files which can be used to contain the contents
of ROM or other boot code needed by simulators. of ROM or other boot code needed by simulators.
Current Internal ROM files being built: Current Internal ROM files being built:
ROM/Boot File: Include File: ROM/Boot File: Include File: Size: Checksum:
======================================= =======================================================================================
VAX/ka655x.bin VAX/vax_ka655x_bin.h
VAX/vmb.exe VAX/vax780_vmb_exe.h
*/ */
struct ROM_File_Descriptor {
char *BinaryName; char *IncludeFileName; size_t expected_size; unsigned int checksum; char *ArrayName;} ROMs[] = {
{"VAX/ka655x.bin", "VAX/vax_ka655x_bin.h", 131072, 0xFF7673B6, "vax_ka655x_bin"},
{"VAX/vmb.exe", "VAX/vax780_vmb_exe.h", 44544, 0xFFC014CC, "vax780_vmb_exe"},
};
#include <time.h>
#include <stdio.h> #include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <sys/stat.h> #include <sys/stat.h>
#if defined(_WIN32) #if defined(_WIN32)
@ -53,6 +57,114 @@
#include <utime.h> #include <utime.h>
#endif #endif
int sim_read_ROM_include(const char *include_filename,
int *psize,
unsigned char **pROMData,
unsigned int *pchecksum,
char **prom_array_name)
{
FILE *iFile;
char line[256];
size_t i;
size_t bytes_written = 0;
size_t allocated_size = 0;
*psize = 0;
*pchecksum = 0;
*pROMData = NULL;
*prom_array_name = NULL;
if (NULL == (iFile = fopen (include_filename, "r")))
return -1;
memset (line, 0, sizeof (line));
while (fgets (line, sizeof(line)-1, iFile)) {
unsigned int byte;
char *c;
switch (line[0]) {
case '#':
case ' ':
case '/':
case '*':
case '\n':
break;
case 'u': /* unsigned char {array_name}[] */
*prom_array_name = calloc(512, sizeof(char));
if (1 == sscanf (line, "unsigned char %s[]", *prom_array_name)) {
c = strchr (*prom_array_name, '[');
if (c)
*c = '\0';
}
break;
case '0': /* line containing byte data */
c = line;
while (1 == sscanf (c, "0x%2Xd,", &byte)) {
if (bytes_written >= allocated_size) {
allocated_size += 2048;
*pROMData = realloc(*pROMData, allocated_size);
}
*(*pROMData + bytes_written++) = byte;
c += 5;
}
break;
}
if (strchr (line, '}'))
break;
}
fclose (iFile);
for (i=0; i<bytes_written; ++i)
*pchecksum += *(*pROMData + i);
*pchecksum = ~*pchecksum;
*psize = bytes_written;
return 0;
}
int sim_make_ROMs_entry(const char *rom_filename)
{
FILE *rFile;
struct stat statb;
unsigned char *ROMData = NULL;
unsigned int checksum = 0;
char *c;
int i;
char include_filename[512];
char array_name[512];
if (NULL == (rFile = fopen (rom_filename, "rb"))) {
printf ("Error Opening ROM binary file '%s' for input: %s\n", rom_filename, strerror(errno));
return -1;
}
if (stat (rom_filename, &statb)) {
printf ("Error stating '%s': %s\n", rom_filename, strerror(errno));
fclose (rFile);
return -1;
}
ROMData = malloc (statb.st_size);
if ((size_t)(statb.st_size) != fread (ROMData, sizeof(*ROMData), statb.st_size, rFile)) {
printf ("Error reading '%s': %s\n", rom_filename, strerror(errno));
fclose (rFile);
free (ROMData);
return -1;
}
fclose (rFile);
for (i=0; i<statb.st_size; ++i)
checksum += ROMData[i];
checksum = ~checksum;
sprintf (include_filename, "%s.h", rom_filename);
if ((c = strchr (include_filename, '.')))
*c = '_';
if (!(c = strchr (rom_filename, '/')))
c = strchr (rom_filename, '/');
strcpy (array_name, c);
if ((c = strchr (array_name, '.')))
*c = '_';
printf ("The ROMs array entry for this new ROM image file should look something like:\n");
printf ("{\"%s\", \"%s\", %d, 0x%08X, \"%s\"}\n",
rom_filename, include_filename, (int)(statb.st_size), checksum, array_name);
return 1;
}
int sim_make_ROM_include(const char *rom_filename, int sim_make_ROM_include(const char *rom_filename,
int expected_size, int expected_size,
unsigned int expected_checksum, unsigned int expected_checksum,
@ -63,14 +175,33 @@ FILE *rFile;
FILE *iFile; FILE *iFile;
time_t now; time_t now;
int bytes_written = 0; int bytes_written = 0;
int include_bytes;
int c; int c;
struct stat statb; struct stat statb;
unsigned char *ROMData = NULL; unsigned char *ROMData = NULL;
unsigned char *include_ROMData = NULL;
char *include_array_name = NULL;
unsigned int checksum = 0; unsigned int checksum = 0;
unsigned int include_checksum;
if (NULL == (rFile = fopen (rom_filename, "rb"))) { if (NULL == (rFile = fopen (rom_filename, "rb"))) {
printf ("Error Opening '%s' for input: %s\n", rom_filename, strerror(errno)); printf ("Error Opening ROM binary file '%s' for input: %s\n", rom_filename, strerror(errno));
return -1; if (0 != sim_read_ROM_include(include_filename,
&include_bytes,
&include_ROMData,
&include_checksum,
&include_array_name))
return -1;
c = ((include_checksum == expected_checksum) &&
(include_bytes == expected_size) &&
(0 == strcmp(include_array_name, rom_array_name)));
free(include_ROMData);
free(include_array_name);
if (!c)
printf ("Existing ROM include file: %s has unexpected content\n", include_filename);
else
printf ("Existing ROM include file: %s looks good\n", include_filename);
return (c ? 0 : -1);
} }
if (stat (rom_filename, &statb)) { if (stat (rom_filename, &statb)) {
printf ("Error stating '%s': %s\n", rom_filename, strerror(errno)); printf ("Error stating '%s': %s\n", rom_filename, strerror(errno));
@ -108,35 +239,18 @@ if ((expected_checksum != 0) && (checksum != expected_checksum)) {
* If the target include file already exists, determine if it contains the exact * If the target include file already exists, determine if it contains the exact
* data in the base ROM image. If so, then we are already done * data in the base ROM image. If so, then we are already done
*/ */
if (NULL != (iFile = fopen (include_filename, "r"))) { if (0 == sim_read_ROM_include(include_filename,
unsigned char *IncludeData = NULL; &include_bytes,
char line[256]; &include_ROMData,
int Difference = 0; &include_checksum,
&include_array_name)) {
IncludeData = malloc (statb.st_size); c = ((include_checksum == expected_checksum) &&
(include_bytes == expected_size) &&
while (fgets (line, sizeof(line), iFile)) { (0 == strcmp (include_array_name, rom_array_name)) &&
unsigned int byte; (0 == memcmp (include_ROMData, ROMData, include_bytes)));
char *c; free(include_ROMData);
free(include_array_name);
if (memcmp ("0x",line,2)) if (c) {
continue;
c = line;
while (1 == sscanf (c, "0x%2Xd,", &byte)) {
if (bytes_written >= statb.st_size)
Difference = 1;
else
IncludeData[bytes_written++] = byte;
c += 5;
}
if ((strchr (line,'}')) || Difference)
break;
}
fclose (iFile);
if (!Difference)
Difference = memcmp (IncludeData, ROMData, statb.st_size);
free (IncludeData);
if (!Difference) {
free (ROMData); free (ROMData);
return 0; return 0;
} }
@ -153,6 +267,7 @@ fprintf (iFile, "/*\n");
fprintf (iFile, " %s produced at %s", include_filename, ctime(&now)); fprintf (iFile, " %s produced at %s", include_filename, ctime(&now));
fprintf (iFile, " from %s which was last modified at %s", rom_filename, ctime(&statb.st_mtime)); fprintf (iFile, " from %s which was last modified at %s", rom_filename, ctime(&statb.st_mtime));
fprintf (iFile, " file size: %d (0x%X) - checksum: 0x%08X\n", (int)statb.st_size, (int)statb.st_size, checksum); fprintf (iFile, " file size: %d (0x%X) - checksum: 0x%08X\n", (int)statb.st_size, (int)statb.st_size, checksum);
fprintf (iFile, " This file is a generated file and should NOT be edited or changed by hand.\n");
fprintf (iFile, "*/\n"); fprintf (iFile, "*/\n");
fprintf (iFile, "unsigned char %s[] = {", rom_array_name); fprintf (iFile, "unsigned char %s[] = {", rom_array_name);
for (bytes_written=0;bytes_written<statb.st_size; ++bytes_written) { for (bytes_written=0;bytes_written<statb.st_size; ++bytes_written) {
@ -175,11 +290,63 @@ if (1) { /* Set Modification Time on the include file to be the modification tim
return 0; return 0;
} }
void
Usage(void)
{
int i;
printf ("sim_BuildROMs Usage:\n");
printf ("sim_BuildROMs\n");
printf (" invoked with no arguments will verify and/or produce all\n");
printf (" known ROM include files\n");
printf ("sim_BuildROMs -checksum ROM-File-name\n");
printf (" computes the checksum on a ROM image file and provides a\n");
printf (" template which can be added to the ROMs array in the\n");
printf (" source file sim_BuildROMs.c\n");
printf ("sim_BuildROMs ROM-File-name\n");
printf (" if the 'ROM-File-name' specified is a file name already\n");
printf (" contained in the ROMs array, only that ROM image file's\n");
printf (" include file will be verified and/or created\n");
printf (" if the 'ROM-File-name' specified is not a file name already\n");
printf (" contained in the ROMs array, that ROM's checksum is computed\n");
printf (" and a template which can be added to the ROMs array in the\n");
printf (" source file sim_BuildROMs.c is displayed.\n");
printf ("\n");
printf ("Current ROM files:\n");
printf ("\n");
printf ("BinaryName: IncludeFileName: Size: Checksum: ROM Array Name:\n");
printf ("=============================================================================\n");
for (i=0; i<sizeof(ROMs)/sizeof(ROMs[0]); ++i)
printf("%-17s%-23s%8d 0x%08X %s\n", ROMs[i].BinaryName, ROMs[i].IncludeFileName, (int)ROMs[i].expected_size, ROMs[i].checksum, ROMs[i].ArrayName);
exit(2);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int i;
int status = 0; int status = 0;
status += sim_make_ROM_include ("VAX/ka655x.bin", 131072, 0xFF7673B6, "VAX/vax_ka655x_bin.h", "vax_ka655x_bin");
status += sim_make_ROM_include ("VAX/vmb.exe", 44544, 0xFFC014CC, "VAX/vax780_vmb_exe.h", "vax780_vmb_exe"); if (argc == 1) { /* invoked without any arguments */
for (i=0; i<sizeof(ROMs)/sizeof(ROMs[0]); ++i)
status += sim_make_ROM_include (ROMs[i].BinaryName, ROMs[i].expected_size, ROMs[i].checksum, ROMs[i].IncludeFileName, ROMs[i].ArrayName);
exit((status == 0) ? 0 : 2);
}
if ((0 == strcmp(argv[1], "/?")) ||
(0 == strcmp(argv[1], "-?")) ||
(0 == strcmp(argv[1], "/help")) ||
(0 == strcmp(argv[1], "-help")))
Usage();
if ((0 == strcmp(argv[1], "-checksum")) && (argc > 2))
status = sim_make_ROMs_entry (argv[2]);
else {
for (i=0; i<sizeof(ROMs)/sizeof(ROMs[0]); ++i)
if (0 == strcmp(argv[1], ROMs[i].BinaryName))
break;
if (i == sizeof(ROMs)/sizeof(ROMs[0]))
status = sim_make_ROMs_entry (argv[1]);
else
status = sim_make_ROM_include (ROMs[i].BinaryName, ROMs[i].expected_size, ROMs[i].checksum, ROMs[i].IncludeFileName, ROMs[i].ArrayName);
}
exit((status == 0) ? 0 : 2); exit((status == 0) ? 0 : 2);
} }