summaryrefslogtreecommitdiff
path: root/util/BuildImage.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--util/BuildImage.c380
1 files changed, 193 insertions, 187 deletions
diff --git a/util/BuildImage.c b/util/BuildImage.c
index 2124c9d..42430ce 100644
--- a/util/BuildImage.c
+++ b/util/BuildImage.c
@@ -14,27 +14,27 @@
**
*/
-#define _POSIX_C_SOURCE 200809L
+#define _POSIX_C_SOURCE 200809L
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <string.h>
-#include <errno.h>
+#include <unistd.h>
-#define TRUE 1
-#define FALSE 0
+#define TRUE 1
+#define FALSE 0
-#define DRIVE_FLOPPY 0x00
-#define DRIVE_USB 0x80
+#define DRIVE_FLOPPY 0x00
+#define DRIVE_USB 0x80
-#define SECT_SIZE 512
+#define SECT_SIZE 512
-char *progname; /* invocation name of this program */
-char *bootstrap_filename; /* path of file holding bootstrap program */
-char *output_filename; /* path of disk image file */
-FILE *out; /* output stream for disk image file */
-short drive = DRIVE_USB; /* boot drive */
+char *progname; /* invocation name of this program */
+char *bootstrap_filename; /* path of file holding bootstrap program */
+char *output_filename; /* path of disk image file */
+FILE *out; /* output stream for disk image file */
+short drive = DRIVE_USB; /* boot drive */
/*
** Array into which program information will be stored, starting at the
@@ -46,9 +46,9 @@ short drive = DRIVE_USB; /* boot drive */
** can be loaded.
*/
-#define N_INFO ( SECT_SIZE / sizeof( short ) )
+#define N_INFO (SECT_SIZE / sizeof(short))
-short info[ N_INFO ];
+short info[N_INFO];
int n_info = N_INFO;
/**
@@ -60,43 +60,46 @@ int n_info = N_INFO;
**
** does not return
*/
-void quit( char *msg, int call_perror ) {
- if( msg != NULL ){
+void quit(char *msg, int call_perror)
+{
+ if (msg != NULL) {
// preserve the error code in case we need it
int err_num = errno;
- fprintf( stderr, "%s: ", progname );
+ fprintf(stderr, "%s: ", progname);
errno = err_num;
- if( call_perror ){
- perror( msg );
+ if (call_perror) {
+ perror(msg);
} else {
- fprintf( stderr, "%s\n", msg );
+ fprintf(stderr, "%s\n", msg);
}
}
- if( output_filename != NULL ){
- unlink( output_filename );
+ if (output_filename != NULL) {
+ unlink(output_filename);
}
- exit( EXIT_FAILURE );
+ exit(EXIT_FAILURE);
// NOTREACHED
}
-const char usage_error_msg[] =
- "\nUsage: %s [ -d drive ] -b bootfile -o outfile { progfile loadpt } ...\n\n"
- "\t'drive' is either 'floppy' or 'usb' (default 'usb')\n\n"
- "\tThere must be at least one program file and load point.\n\n"
- "\tLoad points may be specified either as 32-bit quantities in hex,\n"
- "\tdecimal or octal (e.g. 0x10c00, 68608, 0206000 are all equivalent),\n"
- "\tor as an explicit segment:offset pair whose digits are always\n"
- "\tinterpreted as hexadecimal values (e.g. 10c0:0000, 1000:0c00 are\n"
- "\tboth equivalent to the previous examples).\n\n";
+const char usage_error_msg[] =
+ "\nUsage: %s [ -d drive ] -b bootfile -o outfile { progfile loadpt } "
+ "...\n\n"
+ "\t'drive' is either 'floppy' or 'usb' (default 'usb')\n\n"
+ "\tThere must be at least one program file and load point.\n\n"
+ "\tLoad points may be specified either as 32-bit quantities in hex,\n"
+ "\tdecimal or octal (e.g. 0x10c00, 68608, 0206000 are all equivalent),\n"
+ "\tor as an explicit segment:offset pair whose digits are always\n"
+ "\tinterpreted as hexadecimal values (e.g. 10c0:0000, 1000:0c00 are\n"
+ "\tboth equivalent to the previous examples).\n\n";
/**
** print a usage message and then call quit()
**
** does not return
*/
-void usage_error( void ){
- fprintf( stderr, usage_error_msg, progname );
- quit( NULL, FALSE );
+void usage_error(void)
+{
+ fprintf(stderr, usage_error_msg, progname);
+ quit(NULL, FALSE);
// NOTREACHED
}
@@ -107,29 +110,30 @@ void usage_error( void ){
** @param in open FILE to be read
** @return the number of sectors copied from the file
*/
-int copy_file( FILE *in ){
+int copy_file(FILE *in)
+{
int n_sectors = 0;
- char buf[ SECT_SIZE ];
+ char buf[SECT_SIZE];
int n_bytes;
int i;
/*
- ** Copy the file to the output, being careful that the
- ** last sector is padded with null bytes out to the
- ** sector size.
- */
+ ** Copy the file to the output, being careful that the
+ ** last sector is padded with null bytes out to the
+ ** sector size.
+ */
n_sectors = 0;
- while( (n_bytes = fread( buf, 1, sizeof( buf ), in )) > 0 ){
+ while ((n_bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
// pad this sector out to block size
- if( n_bytes < sizeof( buf ) ){
+ if (n_bytes < sizeof(buf)) {
int i;
- for( i = n_bytes; i < sizeof( buf ); i += 1 ){
- buf[ i ] = '\0';
+ for (i = n_bytes; i < sizeof(buf); i += 1) {
+ buf[i] = '\0';
}
}
- if( fwrite( buf, 1, sizeof( buf ), out ) != sizeof( buf ) ){
- quit( "Write failed or was wrong size", FALSE );
+ if (fwrite(buf, 1, sizeof(buf), out) != sizeof(buf)) {
+ quit("Write failed or was wrong size", FALSE);
}
n_sectors += 1;
}
@@ -143,85 +147,85 @@ int copy_file( FILE *in ){
** @param name path to the file to be copied
** @param addr string containing the load address
*/
-void process_file( char *name, char *addr ){
+void process_file(char *name, char *addr)
+{
long address;
short segment, offset;
int n_bytes;
/*
- ** Open the input file.
- */
- FILE *in = fopen( name, "rb" );
- if( in == NULL ){
- quit( name, TRUE );
+ ** Open the input file.
+ */
+ FILE *in = fopen(name, "rb");
+ if (in == NULL) {
+ quit(name, TRUE);
}
/*
- ** Copy the file to the output, being careful that the
- ** last block is padded with null bytes.
- */
- int n_sectors = copy_file( in );
- fclose( in );
+ ** Copy the file to the output, being careful that the
+ ** last block is padded with null bytes.
+ */
+ int n_sectors = copy_file(in);
+ fclose(in);
/*
- ** Decode the address they gave us. We'll accept two forms:
- ** "nnnn:nnnn" for a segment:offset value (assumed to be hex),
- ** "nnnnnnn" for a decimal, hex, or octal value
- */
+ ** Decode the address they gave us. We'll accept two forms:
+ ** "nnnn:nnnn" for a segment:offset value (assumed to be hex),
+ ** "nnnnnnn" for a decimal, hex, or octal value
+ */
int valid_address = FALSE;
- char *cp = strchr( addr, ':' );
- if( cp != NULL ){
+ char *cp = strchr(addr, ':');
+ if (cp != NULL) {
// must be in nnnn:nnnn form exactly
- if( strlen( addr ) == 9 && cp == addr + 4 ){
+ if (strlen(addr) == 9 && cp == addr + 4) {
char *ep1, *ep2;
int a1, a2;
- segment = strtol( addr, &ep1, 16 );
- offset = strtol( addr + 5, &ep2, 16 );
- address = ( segment << 4 ) + offset;
+ segment = strtol(addr, &ep1, 16);
+ offset = strtol(addr + 5, &ep2, 16);
+ address = (segment << 4) + offset;
valid_address = *ep1 == '\0' && *ep2 == '\0';
} else {
- fprintf( stderr, "Bad address format - '%s'\n", addr );
- quit( NULL, FALSE );
+ fprintf(stderr, "Bad address format - '%s'\n", addr);
+ quit(NULL, FALSE);
}
} else {
// just a number, possibly hex or octal
char *ep;
- address = strtol( addr, &ep, 0 );
- segment = (short)( address >> 4 );
- offset = (short)( address & 0xf );
+ address = strtol(addr, &ep, 0);
+ segment = (short)(address >> 4);
+ offset = (short)(address & 0xf);
valid_address = *ep == '\0' && address <= 0x0009ffff;
}
- if( !valid_address ){
- fprintf( stderr, "%s: Invalid address: %s\n", progname, addr );
- quit( NULL, FALSE );
+ if (!valid_address) {
+ fprintf(stderr, "%s: Invalid address: %s\n", progname, addr);
+ quit(NULL, FALSE);
}
/*
- ** Make sure the program will fit!
- */
- if( address + n_sectors * SECT_SIZE > 0x0009ffff ){
- fprintf( stderr, "Program %s too large to start at 0x%08x\n",
- name, (unsigned int) address );
- quit( NULL, FALSE );
+ ** Make sure the program will fit!
+ */
+ if (address + n_sectors * SECT_SIZE > 0x0009ffff) {
+ fprintf(stderr, "Program %s too large to start at 0x%08x\n", name,
+ (unsigned int)address);
+ quit(NULL, FALSE);
}
- if( n_info < 3 ){
- quit( "Too many programs!", FALSE );
+ if (n_info < 3) {
+ quit("Too many programs!", FALSE);
}
-
/*
- ** Looks good: report and store the information.
- */
- fprintf( stderr, " %s: %d sectors, loaded at 0x%x\n",
- name, n_sectors, (unsigned int) address );
+ ** Looks good: report and store the information.
+ */
+ fprintf(stderr, " %s: %d sectors, loaded at 0x%x\n", name, n_sectors,
+ (unsigned int)address);
- info[ --n_info ] = n_sectors;
- info[ --n_info ] = segment;
- info[ --n_info ] = offset;
+ info[--n_info] = n_sectors;
+ info[--n_info] = segment;
+ info[--n_info] = offset;
}
/*
@@ -237,64 +241,65 @@ extern char *optarg;
** @param ac the count of entries in av
** @param av the argument vector
*/
-void process_args( int ac, char **av ) {
+void process_args(int ac, char **av)
+{
int c;
-
- while( (c=getopt(ac,av,":d:o:b:")) != EOF ) {
-
- switch( c ) {
- case ':': /* missing arg value */
- fprintf( stderr, "missing operand after -%c\n", optopt );
+ while ((c = getopt(ac, av, ":d:o:b:")) != EOF) {
+ switch (c) {
+ case ':': /* missing arg value */
+ fprintf(stderr, "missing operand after -%c\n", optopt);
/* FALL THROUGH */
- case '?': /* error */
+ case '?': /* error */
usage_error();
/* NOTREACHED */
- case 'b': /* -b bootstrap_file */
+ case 'b': /* -b bootstrap_file */
bootstrap_filename = optarg;
break;
- case 'd': /* -d drive */
- switch( *optarg ) {
- case 'f': drive = DRIVE_FLOPPY; break;
- case 'u': drive = DRIVE_USB; break;
- default: usage_error();
+ case 'd': /* -d drive */
+ switch (*optarg) {
+ case 'f':
+ drive = DRIVE_FLOPPY;
+ break;
+ case 'u':
+ drive = DRIVE_USB;
+ break;
+ default:
+ usage_error();
}
break;
- case 'o': /* -o output_file */
+ case 'o': /* -o output_file */
output_filename = optarg;
break;
-
+
default:
usage_error();
-
}
-
}
- if( !bootstrap_filename ) {
- fprintf( stderr, "%s: no bootstrap file specified\n", progname );
- exit( 2 );
+ if (!bootstrap_filename) {
+ fprintf(stderr, "%s: no bootstrap file specified\n", progname);
+ exit(2);
}
- if( !output_filename ) {
- fprintf( stderr, "%s: no disk image file specified\n", progname );
- exit( 2 );
+ if (!output_filename) {
+ fprintf(stderr, "%s: no disk image file specified\n", progname);
+ exit(2);
}
/*
- ** Must have at least two remaining arguments (file to load,
- ** address at which it should be loaded), and must have an
- ** even number of remaining arguments.
- */
+ ** Must have at least two remaining arguments (file to load,
+ ** address at which it should be loaded), and must have an
+ ** even number of remaining arguments.
+ */
int remain = ac - optind;
- if( remain < 2 || (remain & 1) != 0 ) {
+ if (remain < 2 || (remain & 1) != 0) {
usage_error();
}
-
}
/**
@@ -307,109 +312,110 @@ void process_args( int ac, char **av ) {
** @param av command-line argument vector
** @return EXIT_SUCCESS or EXIT_FAILURE
*/
-int main( int ac, char **av ) {
- FILE *bootimage;
- int bootimage_size;
- int n_bytes, n_words;
- short existing_data[ N_INFO ];
- int i;
-
+int main(int ac, char **av)
+{
+ FILE *bootimage;
+ int bootimage_size;
+ int n_bytes, n_words;
+ short existing_data[N_INFO];
+ int i;
+
/*
- ** Save the program name for error messages
- */
- progname = strrchr( av[ 0 ], '/' );
- if( progname != NULL ){
+ ** Save the program name for error messages
+ */
+ progname = strrchr(av[0], '/');
+ if (progname != NULL) {
progname++;
} else {
- progname = av[ 0 ];
+ progname = av[0];
}
/*
- ** Process arguments
- */
- process_args( ac, av );
+ ** Process arguments
+ */
+ process_args(ac, av);
/*
- ** Open the output file
- */
+ ** Open the output file
+ */
- out = fopen( output_filename, "wb+" );
- if( out == NULL ){
- quit( output_filename, TRUE );
+ out = fopen(output_filename, "wb+");
+ if (out == NULL) {
+ quit(output_filename, TRUE);
}
/*
- ** Open the bootstrap file and copy it to the output image.
- */
- bootimage = fopen( bootstrap_filename, "rb" );
- if( bootimage == NULL ){
- quit( bootstrap_filename, TRUE );
+ ** Open the bootstrap file and copy it to the output image.
+ */
+ bootimage = fopen(bootstrap_filename, "rb");
+ if (bootimage == NULL) {
+ quit(bootstrap_filename, TRUE);
}
/*
- ** Remember the size of the bootstrap for later, as we
- ** need to patch some things into it
- */
- int n_sectors = copy_file( bootimage );
- fclose( bootimage );
+ ** Remember the size of the bootstrap for later, as we
+ ** need to patch some things into it
+ */
+ int n_sectors = copy_file(bootimage);
+ fclose(bootimage);
bootimage_size = n_sectors * SECT_SIZE;
- fprintf( stderr, " %s: %d sectors\n", bootstrap_filename, n_sectors );
+ fprintf(stderr, " %s: %d sectors\n", bootstrap_filename, n_sectors);
/*
- ** Process the programs one by one
- */
+ ** Process the programs one by one
+ */
ac -= optind;
av += optind;
- while( ac >= 2 ){
- process_file( av[ 0 ], av[ 1 ] );
- ac -= 2; av += 2;
+ while (ac >= 2) {
+ process_file(av[0], av[1]);
+ ac -= 2;
+ av += 2;
}
/*
- ** Check for oddball leftover argument
- */
- if( ac > 0 ){
+ ** Check for oddball leftover argument
+ */
+ if (ac > 0) {
usage_error();
}
/*
- ** Seek to where the array of module data must begin and read
- ** what's already there.
- */
- n_words = ( N_INFO - n_info );
- n_bytes = n_words * sizeof( info[ 0 ] );
- fseek( out, bootimage_size - n_bytes, SEEK_SET );
- if( fread( existing_data, sizeof(info[0]), n_words, out ) != n_words ){
- quit( "Read from boot image failed or was too short", FALSE );
+ ** Seek to where the array of module data must begin and read
+ ** what's already there.
+ */
+ n_words = (N_INFO - n_info);
+ n_bytes = n_words * sizeof(info[0]);
+ fseek(out, bootimage_size - n_bytes, SEEK_SET);
+ if (fread(existing_data, sizeof(info[0]), n_words, out) != n_words) {
+ quit("Read from boot image failed or was too short", FALSE);
}
/*
- ** If that space is non-zero, we have a problem
- */
- for( i = 0; i < n_words; i += 1 ){
- if( existing_data[ i ] != 0 ){
- quit( "Too many programs to load!", FALSE );
+ ** If that space is non-zero, we have a problem
+ */
+ for (i = 0; i < n_words; i += 1) {
+ if (existing_data[i] != 0) {
+ quit("Too many programs to load!", FALSE);
}
}
/*
- ** We know that we're only overwriting zeros at the end of
- ** the bootstrap image, so it is ok to go ahead and do it.
- */
- fseek( out, bootimage_size - n_bytes, SEEK_SET );
- if( fwrite( info + n_info, sizeof( info[ 0 ] ), n_words, out ) != n_words ){
- quit( "Write to boot image failed or was too short", FALSE );
+ ** We know that we're only overwriting zeros at the end of
+ ** the bootstrap image, so it is ok to go ahead and do it.
+ */
+ fseek(out, bootimage_size - n_bytes, SEEK_SET);
+ if (fwrite(info + n_info, sizeof(info[0]), n_words, out) != n_words) {
+ quit("Write to boot image failed or was too short", FALSE);
}
/*
- ** Write the drive index to the image.
- */
- fseek( out, 508, SEEK_SET );
- fwrite( (void *)&drive, sizeof(drive), 1, out );
+ ** Write the drive index to the image.
+ */
+ fseek(out, 508, SEEK_SET);
+ fwrite((void *)&drive, sizeof(drive), 1, out);
- fclose( out );
+ fclose(out);
return EXIT_SUCCESS;
-
}