185 lines
6.6 KiB
C
185 lines
6.6 KiB
C
/* sim_buildROMs.c: Boot ROM / Boot program load internal support
|
|
|
|
Copyright (c) 2011, Mark Pizzolato
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the "Software"),
|
|
to deal in the Software without restriction, including without limitation
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
MARK PIZZOLATO BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
Except as contained in this notice, the name of Robert M Supnik shall not be
|
|
used in advertising or otherwise to promote the sale, use or other dealings
|
|
in this Software without prior written authorization from Robert M Supnik.
|
|
|
|
-
|
|
|
|
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
|
|
|
|
|
|
*/
|
|
|
|
#include <time.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
|
|
#if defined(_WIN32)
|
|
#include <sys/utime.h>
|
|
#define utimbuf _utimbuf
|
|
#define utime _utime
|
|
#else
|
|
#include <utime.h>
|
|
#endif
|
|
|
|
int sim_make_ROM_include(const char *rom_filename,
|
|
int expected_size,
|
|
unsigned int expected_checksum,
|
|
const char *include_filename,
|
|
const char *rom_array_name)
|
|
{
|
|
FILE *rFile;
|
|
FILE *iFile;
|
|
time_t now;
|
|
int bytes_written = 0;
|
|
int c;
|
|
struct stat statb;
|
|
unsigned char *ROMData = NULL;
|
|
unsigned int checksum = 0;
|
|
|
|
if (NULL == (rFile = fopen (rom_filename, "rb"))) {
|
|
printf ("Error Opening '%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;
|
|
}
|
|
if (statb.st_size != expected_size) {
|
|
printf ("Error: ROM file '%s' has an unexpected size: %d vs %d\n", rom_filename, (int)statb.st_size, expected_size);
|
|
printf ("This can happen if the file was transferred or unpacked incorrectly\n");
|
|
printf ("and in the process tried to convert line endings rather than passing\n");
|
|
printf ("the file's contents unmodified\n");
|
|
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 (c=0; c<statb.st_size; ++c)
|
|
checksum += ROMData[c];
|
|
checksum = ~checksum;
|
|
if ((expected_checksum != 0) && (checksum != expected_checksum)) {
|
|
printf ("Error: ROM file '%s' has an unexpected checksum: 0x%08X vs 0x%08X\n", rom_filename, checksum, expected_checksum);
|
|
printf ("This can happen if the file was transferred or unpacked incorrectly\n");
|
|
printf ("and in the process tried to convert line endings rather than passing\n");
|
|
printf ("the file's contents unmodified\n");
|
|
fclose (rFile);
|
|
return -1;
|
|
}
|
|
/*
|
|
* 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) {
|
|
free (ROMData);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (NULL == (iFile = fopen (include_filename, "w"))) {
|
|
printf ("Error Opening '%s' for output: %s\n", include_filename, strerror(errno));
|
|
return -1;
|
|
}
|
|
time (&now);
|
|
fprintf (iFile, "#ifndef ROM_%s_H\n", rom_array_name);
|
|
fprintf (iFile, "#define ROM_%s_H 0\n", rom_array_name);
|
|
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, "*/\n");
|
|
fprintf (iFile, "unsigned char %s[] = {", rom_array_name);
|
|
for (bytes_written=0;bytes_written<statb.st_size; ++bytes_written) {
|
|
c = ROMData[bytes_written];
|
|
if (0 == bytes_written%16)
|
|
fprintf (iFile,"\n");
|
|
fprintf (iFile,"0x%02X,", c&0xFF);
|
|
}
|
|
free (ROMData);
|
|
fprintf (iFile,"};\n");
|
|
fprintf (iFile, "#endif /* ROM_%s_H */\n", rom_array_name);
|
|
fclose (iFile);
|
|
if (1) { /* Set Modification Time on the include file to be the modification time of the ROM file */
|
|
struct utimbuf times;
|
|
|
|
times.modtime = statb.st_mtime;
|
|
times.actime = statb.st_atime;
|
|
utime (include_filename, ×);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
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");
|
|
exit((status == 0) ? 0 : 2);
|
|
}
|