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
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
of ROM or other boot code needed by simulators.
Current Internal ROM files being built:
ROM/Boot File: Include File:
=======================================
VAX/ka655x.bin VAX/vax_ka655x_bin.h
VAX/vmb.exe VAX/vax780_vmb_exe.h
ROM/Boot File: Include File: Size: Checksum:
=======================================================================================
*/
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 <errno.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#if defined(_WIN32)
@ -53,6 +57,114 @@
#include <utime.h>
#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 expected_size,
unsigned int expected_checksum,
@ -63,14 +175,33 @@ FILE *rFile;
FILE *iFile;
time_t now;
int bytes_written = 0;
int include_bytes;
int c;
struct stat statb;
unsigned char *ROMData = NULL;
unsigned char *include_ROMData = NULL;
char *include_array_name = NULL;
unsigned int checksum = 0;
unsigned int include_checksum;
if (NULL == (rFile = fopen (rom_filename, "rb"))) {
printf ("Error Opening '%s' for input: %s\n", rom_filename, strerror(errno));
return -1;
printf ("Error Opening ROM binary file '%s' for input: %s\n", rom_filename, strerror(errno));
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)) {
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
* data in the base ROM image. If so, then we are already done
*/
if (NULL != (iFile = fopen (include_filename, "r"))) {
unsigned char *IncludeData = NULL;
char line[256];
int Difference = 0;
IncludeData = malloc (statb.st_size);
while (fgets (line, sizeof(line), iFile)) {
unsigned int byte;
char *c;
if (memcmp ("0x",line,2))
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) {
if (0 == sim_read_ROM_include(include_filename,
&include_bytes,
&include_ROMData,
&include_checksum,
&include_array_name)) {
c = ((include_checksum == expected_checksum) &&
(include_bytes == expected_size) &&
(0 == strcmp (include_array_name, rom_array_name)) &&
(0 == memcmp (include_ROMData, ROMData, include_bytes)));
free(include_ROMData);
free(include_array_name);
if (c) {
free (ROMData);
return 0;
}
@ -153,6 +267,7 @@ fprintf (iFile, "/*\n");
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, " 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, "unsigned char %s[] = {", rom_array_name);
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;
}
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
main(int argc, char **argv)
{
int i;
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);
}