aboutsummaryrefslogtreecommitdiff
path: root/blob2xex.c
diff options
context:
space:
mode:
Diffstat (limited to 'blob2xex.c')
-rw-r--r--blob2xex.c94
1 files changed, 68 insertions, 26 deletions
diff --git a/blob2xex.c b/blob2xex.c
index 9740e45..2ff7249 100644
--- a/blob2xex.c
+++ b/blob2xex.c
@@ -32,7 +32,7 @@ int get_offset(const char *arg) {
return (int)got;
}
-void write_segment(
+int write_segment(
const char *infile,
const char *outfile,
int loadaddr,
@@ -47,16 +47,16 @@ void write_segment(
if(size < 1) {
fprintf(stderr, SELF ": invalid size %d (must be >= 1).\n", size);
- exit(1);
+ return(0);
}
if(strcmp(infile, "-") == 0) {
- infh = stdout;
+ infh = stdin;
} else {
infh = fopen(infile, "rb");
if(!infh) {
- perror(outfile);
- exit(1);
+ fprintf(stderr, SELF ": %s: %s\n", infile, strerror(errno));
+ return(0);
}
}
@@ -69,12 +69,18 @@ void write_segment(
} else {
outfh = fopen(outfile, "wb");
if(!outfh) {
- perror(outfile);
- exit(-1);
+ fprintf(stderr, SELF ": %s: %s\n", outfile, strerror(errno));
+ return(0);
}
}
}
+ if(isatty(fileno(outfh))) {
+ fprintf(stderr,
+ SELF ": Standard output is a terminal; not writing binary data\n");
+ return 0;
+ }
+
seg.object = buffer;
seg.len = 0;
seg.start_addr = loadaddr;
@@ -85,11 +91,15 @@ void write_segment(
c = getc(infh);
if(c < 0) {
fprintf(stderr, SELF ": offset extends past EOF on file %s\n", infile);
- exit(1); /* TODO: handle this better? */
+ return(0);
}
offset--;
}
+ /* make sure we don't wrap the Atari's address space. */
+ if(size + loadaddr > 0xffff)
+ size = (size - loadaddr) + 1;
+
/* read <size> bytes, or until EOF (which is not an error) */
while(size) {
c = getc(infh);
@@ -98,8 +108,22 @@ void write_segment(
seg.len++;
size--;
}
+
+ if(seg.len == 0) {
+ fprintf(stderr, SELF ": read 0 bytes from %s, xex files cannot contain empty segments.\n", infile);
+ return(0);
+ }
+
seg.end_addr = seg.start_addr + seg.len - 1;
+ /* if we start/end in ROM, warn, but it's not an error. */
+ if(seg.start_addr >= 0xc000)
+ fprintf(stderr, SELF ": warning: %s: start address $%04x loads into ROM.\n", infile, seg.start_addr);
+
+ if(seg.end_addr >= 0xc000)
+ fprintf(stderr, SELF ": warning: %s: end address $%04x loads into ROM.\n",
+ infile, seg.end_addr);
+
xex_fwrite_seg(&seg, outfh);
if(initaddr >= 0) {
@@ -108,11 +132,13 @@ void write_segment(
}
fclose(infh);
+ return(1);
}
void usage() {
- printf(SELF ": Usage:\n\t"
- SELF " outfile [-r runaddr] [-l loadaddr [-i initaddr] "
+ printf(SELF ": Usage:\n "
+ SELF " outfile [-v] [-r runaddr]\n"
+ " [-l loadaddr ] [-i initaddr] "
"[-o offset] [-s size] infile] ..."
"\nSee man page for details.\n");
}
@@ -120,6 +146,7 @@ void usage() {
int main(int argc, char **argv) {
char *outfile = 0, *infile = 0;
int i, loadaddr = -1, runaddr = -1, initaddr = -1, offset = 0, size = DEFAULT_SIZE, *param = 0;
+ int segcount = 0, incount = 0;
outfile = argv[1];
if(!outfile || strcmp(outfile, "--help") == 0 || strcmp(outfile, "-h") == 0) {
@@ -137,12 +164,6 @@ int main(int argc, char **argv) {
exit(1);
}
- if(argc < 5) {
- fprintf(stderr, SELF ": not enough arguments.\n");
- usage();
- exit(1);
- }
-
for(i = 2; i < argc; i++) {
char *arg = argv[i];
@@ -157,7 +178,7 @@ int main(int argc, char **argv) {
exit(1);
}
param = 0;
- } else if(arg[0] == '-') {
+ } else if(arg[0] == '-' && arg[1] != '\0') {
infile = 0;
switch(arg[1]) {
case 'l': param = &loadaddr; break;
@@ -173,21 +194,33 @@ int main(int argc, char **argv) {
break;
}
} else {
- if(infile) {
- fprintf(stderr, SELF ": input filename without -l option: %s\n", arg);
- usage();
- exit(1);
+ if(loadaddr == -1) {
+ fprintf(stderr, SELF ": input filename without load address (-l): %s\n", arg);
+ segcount = 0;
+ break;
}
infile = arg;
- write_segment(infile, outfile, loadaddr, initaddr, offset, size);
+ incount++;
+ if(write_segment(infile, outfile, loadaddr, initaddr, offset, size)) {
+ segcount++;
+ } else {
+ segcount = 0;
+ break;
+ }
+ infile = 0;
loadaddr = -1; initaddr = -1; offset = 0; size = DEFAULT_SIZE;
}
}
- if(param || (loadaddr >= 0) || (initaddr >= 0) ||
- (offset != 0) || (size != DEFAULT_SIZE)) {
- fprintf(stderr, SELF ": "
- "warning: extra arguments after last input file ignored.\n");
+ if(incount) {
+ if(segcount && ((param || (loadaddr >= 0) || (initaddr >= 0)) ||
+ (offset != 0) || (size != DEFAULT_SIZE)))
+ {
+ fprintf(stderr, SELF ": "
+ "warning: extra arguments after last input file ignored.\n");
+ }
+ } else {
+ fprintf(stderr, SELF ": no input files!\n");
}
if(outfh) {
@@ -201,5 +234,14 @@ int main(int argc, char **argv) {
fclose(outfh);
}
+ if(segcount) {
+ if(xex_verbose)
+ fprintf(stderr, SELF ": read %d input files, wrote %d segments to %s.\n",
+ incount, segcount, outfile);
+ } else {
+ unlink(outfile);
+ return 1;
+ }
+
return 0;
}