From f05c774f3eaf8ab51f05e2c821c8562cb9989e93 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 29 Jul 2013 02:02:50 -0400 Subject: [PATCH] OverlayIIgs --- OverlayIIgs-flags.c | 99 ++++++++++++++++++ OverlayIIgs-flags.h | 20 ++++ OverlayIIgs.c | 237 ++++++++++++++++++++++++++++++++++++++++++++ makefile | 8 +- 4 files changed, 362 insertions(+), 2 deletions(-) create mode 100644 OverlayIIgs-flags.c create mode 100644 OverlayIIgs-flags.h create mode 100644 OverlayIIgs.c diff --git a/OverlayIIgs-flags.c b/OverlayIIgs-flags.c new file mode 100644 index 0000000..7b15baa --- /dev/null +++ b/OverlayIIgs-flags.c @@ -0,0 +1,99 @@ + +#ifdef __ORCAC__ +#pragma optimize 79 +#pragma noroot +#endif + +#include +#include +#include + +#include "OverlayIIgs-flags.h" + +void FlagsHelp(void) +{ + fputs("OverlayIIgs [options] infile outfile\n", stdout); + fputs("-a address set the address\n", stdout); + fputs("\n", stdout); + exit(0); +} + +struct Flags flags; +int FlagsParse(int argc, char **argv) +{ + char *cp; + char *optarg; + + char c; + int i; + int j; + int eof; // end-of-flags + int mindex; // mutation index. + + memset(&flags, 0, sizeof(flags)); + + for (i = 1, mindex = 1, eof = 0; i < argc; ++i) + { + cp = argv[i]; + c = cp[0]; + + if (c != '-' || eof) + { + if (i != mindex) argv[mindex] = argv[i]; + mindex++; + continue; + } + + // -- = end of options. + if (cp[1] == '-' && cp[2] == 0) + { + eof = 1; + continue; + } + + // now scan all the flags in the string... + optarg = NULL; + for (j = 1; ; ++j) + { + c = cp[j]; + if (c == 0) break; + + switch (c) + { + case 'h': + FlagsHelp(); + break; + case 'a': + // -xarg or -x arg + ++j; + if (cp[j]) + { + optarg = cp + j; + } + else + { + if (++i >= argc) + { + fputs("option requires an argument -- a\n", stderr); + exit(1); + } + optarg = argv[i]; + } + flags._a = optarg; + + break; + case 'p': + flags._p = 1; + break; + + default: + fprintf(stderr, "illegal option -- %c\n", c); + exit(1); + } + + if (optarg) break; + } + } + + return mindex; +} diff --git a/OverlayIIgs-flags.h b/OverlayIIgs-flags.h new file mode 100644 index 0000000..feda2c5 --- /dev/null +++ b/OverlayIIgs-flags.h @@ -0,0 +1,20 @@ + +#ifndef __flags_h__ +#define __flags_h__ + +typedef struct Flags { + char *_a; + + unsigned _p:1; + +} Flags; + + +extern struct Flags flags; + +int FlagsParse(int argc, char **argv); + +void FlagsHelp(void); + +#endif + diff --git a/OverlayIIgs.c b/OverlayIIgs.c new file mode 100644 index 0000000..49a59f8 --- /dev/null +++ b/OverlayIIgs.c @@ -0,0 +1,237 @@ +#include +#include +#include +#include + +#include +#include + +#include "OverlayIIgs-flags.h" + +int tox(char c) +{ + c |= 0x20; + if (c >='0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + return 0; +} + + +off_t hex(const char *in) +{ + off_t rv = 0; + + int i; + for (i = 0; ; ++i) + { + off_t tmp; + char c; + + c = *in++; + if (!c) break; + + if (!isxdigit(c)) return -1; + + + tmp = rv; + rv <<= 4; + rv |= tox(c); + + // numver too large. + if (rv < tmp) + { + return -1; + } + } + + if (i == 0) return -1; + + return rv; +} + +off_t dec(const char *in) +{ + off_t rv = 0; + + int i; + for (i = 0; ; ++i) + { + off_t tmp; + char c; + + c = *in++; + if (!c) break; + + if (!isdigit(c)) return -1; + + + tmp = rv; + rv = rv * 10; + rv += c - '0'; + + // numver too large. + if (rv < tmp) + { + return -1; + } + } + + if (i == 0) return -1; + + return rv; +} + +off_t getnum(const char *cp) +{ + if (!cp) return -1; + + if (cp[0] == '$') + { + return hex(cp + 1); + } + + if (cp[0] == '0' && cp[1] == 'x') + { + return hex(cp + 2); + } + return dec(cp); +} + + +int seek_to(int fd, off_t address) +{ + // posix lseek(2) will seek past the eof and zero-fill + // when a write occurs. + + // mpw lseek will fail (ENXIO) in such situations. + // SetEOF will not zero-fill. + + // to compensate, manually zero-fill to the address + // if address > eof. + + off_t eof; + + eof = lseek(fd, 0, SEEK_END); + if (eof < 0) + return -1; + + while (eof < address) + { + static char buffer[512] = { 0 }; + + off_t size = address - eof; + if (size > 512) size = 512; + + size = write(fd, buffer, size); + if (size < 0) return -1; + eof += size; + } + + eof = lseek(fd, address, SEEK_SET); + if (eof < 0) + return -1; + + return 0; +} + +int main(int argc, char **argv) +{ + char *src; + char *dest; + + int srcFD, destFD; + off_t address; + int rv; + + + argc = FlagsParse(argc, argv); + + if (argc != 3) + { + FlagsHelp(); + return 1; + } + + if (!flags._a) + { + FlagsHelp(); + return 1; + } + + address = getnum(flags._a); + if (address == -1) + { + + fprintf(stderr, "Invalid address: %s\n", flags._a); + return 1; + } + + src = argv[1]; + dest = argv[2]; + + srcFD = open(src, O_RDONLY | O_BINARY); + if (srcFD < 0) + { + fprintf(stderr, "Unable to open input file %s: %s", + src, strerror(errno)); + return 1; + } + + destFD = open(dest, O_WRONLY | O_CREAT | O_BINARY); + if (destFD < 0) + { + fprintf(stderr, "Unable to open input file %s: %s", + dest, strerror(errno)); + close(srcFD); + return 1; + } + + + //if (lseek(destFD, address, SEEK_SET) < 0) + if (seek_to(destFD, address) < 0) + { + fprintf(stderr, "Error seeking %s: %s", + dest, strerror(errno)); + close(srcFD); + close(destFD); + return 1; + } + + // copy it + rv = 0; + + for (;;) + { + + unsigned char buffer[4096]; + ssize_t rsize; + ssize_t wsize; + + rsize = read(srcFD, buffer, 4096); + + if (rsize == 0) break; + + if (rsize < 0) + { + fprintf(stderr, "Error reading %s: %s\n", + src, strerror(errno)); + rv = 1; + break; + } + + wsize = write(destFD, buffer, rsize); + if (wsize < 0 || wsize != rsize) + { + fprintf(stderr, "Error writing %s: %s\n", + dest, strerror(errno)); + rv = 1; + break; + } + } + + close(srcFD); + close(destFD); + + + return rv; +} \ No newline at end of file diff --git a/makefile b/makefile index af2c33f..231a525 100644 --- a/makefile +++ b/makefile @@ -26,11 +26,11 @@ LDFLAGS = -w -c 'MPS ' -t MPST \ # LDFLAGS = -d -c 'MPS ' -t MPST -all: Help GetEnv Duplicate SetFile +all: Help GetEnv Duplicate SetFile OverlayIIgs clean: rm -f *.c.o - rm -f Help GetEnv Duplicate SetFile + rm -f Help GetEnv Duplicate SetFile OverlayIIgs GetEnv: GetEnv.c.o mpw Link $(LDFLAGS) -o $@ $^ $(LIBS) @@ -47,6 +47,10 @@ SetFile: SetFile.c.o SetFile-flags.c.o mpw Link $(LDFLAGS) -o $@ $^ $(LIBS) +OverlayIIgs: OverlayIIgs.c.o OverlayIIgs-flags.c.o + mpw Link $(LDFLAGS) -o $@ $^ $(LIBS) + + #SetFile.c : SetFile.rl # ragel -G2 -p -m -o $@ $<