Initial revision
authorceriel <none@none>
Tue, 19 Apr 1988 09:27:51 +0000 (09:27 +0000)
committerceriel <none@none>
Tue, 19 Apr 1988 09:27:51 +0000 (09:27 +0000)
mach/minixST/.distr [new file with mode: 0644]
mach/minixST/Action [new file with mode: 0644]
mach/minixST/cv/.distr [new file with mode: 0644]
mach/minixST/cv/Makefile [new file with mode: 0644]
mach/minixST/cv/cv.c [new file with mode: 0644]

diff --git a/mach/minixST/.distr b/mach/minixST/.distr
new file mode 100644 (file)
index 0000000..f15502b
--- /dev/null
@@ -0,0 +1,3 @@
+Action
+cv
+libsys
diff --git a/mach/minixST/Action b/mach/minixST/Action
new file mode 100644 (file)
index 0000000..9ac53ac
--- /dev/null
@@ -0,0 +1,6 @@
+name "Atari ST Minix systemcall library"
+dir libsys
+end
+name "Atari ST Minix conversion program from ack.out --> Minix ST a.out"
+dir cv
+end
diff --git a/mach/minixST/cv/.distr b/mach/minixST/cv/.distr
new file mode 100644 (file)
index 0000000..d7a861d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+cv.c
diff --git a/mach/minixST/cv/Makefile b/mach/minixST/cv/Makefile
new file mode 100644 (file)
index 0000000..5cfa97a
--- /dev/null
@@ -0,0 +1,25 @@
+EMHOME =       ../../..
+LIBOBJ =       $(EMHOME)/modules/lib/libobject.a
+INCLUDE =      $(EMHOME)/h
+CFLAGS =       -I. -I$(INCLUDE) -O
+TARGETS =      cv
+
+all:           $(TARGETS)
+
+install:       all
+               ../../install cv
+
+cmp:           all
+               ../../compare cv
+
+cv:    cv.o
+               $(CC) $(LDFLAGS) -o cv cv.o $(LIBOBJ)
+
+clean:
+               rm -f $(TARGETS) *.o nohup.out Out
+
+pr:
+               @pr Makefile cv.c
+
+opr:
+               make pr | opr
diff --git a/mach/minixST/cv/cv.c b/mach/minixST/cv/cv.c
new file mode 100644 (file)
index 0000000..709512c
--- /dev/null
@@ -0,0 +1,331 @@
+/* $Header$ */
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ *
+ */
+
+/*
+ * Convert ACK a.out file to ST-Minix object format.
+ */
+
+#include <stdio.h>
+#include <out.h>
+#include <assert.h>
+
+struct outhead outhead;
+struct outsect outsect[S_MAX];
+
+#define TEXTSG 0
+#define ROMSG  1
+#define DATASG 2
+#define BSSSG  3
+#define LSECT  BSSSG+1
+#define NSECT  LSECT+1
+
+char   *output_file;
+int    outputfile_created;
+
+char *program ;
+
+/* Output file definitions and such */
+
+int            output;
+
+int unresolved;
+long   textsize ; 
+long   datasize ;
+long   bsssize;
+
+char *chmemstr;
+
+minixhead()
+{
+       long            mh[8];
+       long            stack;
+       long            chmem();
+       int             i;
+
+       mh[0] = 0x04100301L;
+       mh[1] = 0x00000020L;
+       mh[2] = textsize;
+       mh[3] = datasize;
+       mh[4] = bsssize;
+       mh[5] = 0;
+       stack = 0x00010000L - (mh[3] + mh[4]);
+       if ((mh[0] & 0x00200000L) == 0)         /* not SEPARATE */
+               stack -= mh[2];
+       while (stack < 0)
+               stack += 0x00010000L;
+       if (chmemstr)
+               stack = chmem(chmemstr, stack);
+       printf("%D bytes assigned to stack+malloc area\n", stack);
+       mh[6] = stack + (mh[3] + mh[4]);
+       if ((mh[0] & 0x00200000L) == 0)         /* not SEPARATE */
+               mh[6] += mh[2];
+       mh[7] = 0;
+       for (i = 0; i < 8; i++) {
+               cvlong(&mh[i]);
+       }
+
+       if (write(output, (char *) mh, sizeof(mh)) != sizeof(mh))
+               fatal("write error\n");
+}
+
+long align(a,b)
+       long a,b;
+{
+       if (b == 0) return a;
+       a += b - 1;
+       return a - a % b;
+}
+
+int
+follows(pa, pb)
+       register struct outsect *pa, *pb;
+{
+       /* return 1 if pa follows pb */
+
+       return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
+}
+
+main(argc, argv)
+       int     argc;
+       char    *argv[];
+{
+
+       program= argv[0] ;
+       if (argc > 1) {
+               switch (argv[1][0]) { 
+               case '-':
+               case '+':
+               case '=':
+                       chmemstr = argv[1];
+                       argc--;
+                       argv++;
+               }
+       }
+       switch (argc) {
+       case 3: if ((output = creat(argv[2], 0644)) < 0)
+                       fatal("Can't write %s.\n", argv[2]);
+               output_file = argv[2];
+               outputfile_created = 1;
+               if (! rd_open(argv[1]))
+                       fatal("Can't read %s.\n", argv[1]);
+               break;
+       default:fatal("Usage: %s [+-= amount] <ACK object> <ST-MINIX object>.\n", argv[0]);
+       }
+       rd_ohead(&outhead);
+       if (BADMAGIC(outhead))
+               fatal("Not an ack object file.\n");
+       if (outhead.oh_flags & HF_LINK) {
+               unresolved++;
+               fatal("Contains unresolved references.\n");
+       }
+       if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
+               fatal("Input file must have %d sections, not %ld\n",
+                       NSECT,outhead.oh_nsect) ;
+       rd_sect(outsect, outhead.oh_nsect);
+       /* A few checks */
+       if ( outsect[BSSSG].os_flen != 0 )
+               fatal("bss space contains initialized data\n") ;
+       if (! follows(&outsect[BSSSG], &outsect[DATASG]))
+               fatal("bss segment must follow data segment\n") ;
+       textsize= (outsect[DATASG].os_base - outsect[TEXTSG].os_base);
+       if (! follows(&outsect[ROMSG],&outsect[TEXTSG]))
+               fatal("rom segment must follow text\n") ;
+       if (! follows(&outsect[DATASG],&outsect[ROMSG]))
+               fatal("data segment must follow rom\n") ;
+       outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
+       outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
+       outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
+       datasize= outsect[DATASG].os_size ;
+       bsssize = outsect[BSSSG].os_size;
+       if ( outhead.oh_nsect==NSECT ) {
+               if (! follows(&outsect[LSECT],&outsect[BSSSG]))
+                       fatal("end segment must follow bss\n") ;
+               if ( outsect[LSECT].os_size != 0 )
+                       fatal("end segment must be empty\n") ;
+       }
+
+       minixhead();
+       emits(&outsect[TEXTSG]) ;
+       emits(&outsect[ROMSG]) ;
+       emits(&outsect[DATASG]) ;
+       emit_relo();
+       if ( outputfile_created) chmod(argv[2],0755);
+       return 0;
+}
+
+/*
+ * Transfer the emitted byted from one file to another.
+ */
+emits(section) struct outsect *section ; {
+       char            *p;
+       char            *calloc(), *malloc();
+       long sz = section->os_flen;
+
+       rd_outsect(section - outsect);
+       while (sz) {
+               unsigned int i = (sz >= 0x4000 ? 0x4000 : sz);
+               if (!(p = malloc(0x4000))) {
+                       fatal("No memory.\n");
+               }
+               rd_emit(p, (long) i);
+               if (write(output, p, (int)i) < i) {
+                       fatal("write error.\n");
+               }
+               free(p);
+               sz -= i;
+       }
+
+       sz = section->os_size - section->os_flen;
+       if (sz) {
+               if (!(p = calloc(0x4000, 1))) {
+                       fatal("No memory.\n");
+               }
+               while (sz) {
+                       unsigned int i = (sz >= 0x4000 ? 0x4000 : sz);
+                       if (write(output, p, (int)i) < i) {
+                               fatal("write error.\n");
+                       }
+                       sz -= i;
+               }
+               free(p);
+       }
+}
+
+int
+compare(a,b)
+       register struct outrelo *a, *b;
+{
+       if (a->or_sect < b->or_sect) return -1;
+       if (a->or_sect > b->or_sect) return 1;
+       if (a->or_addr < b->or_addr) return -1;
+       if (a->or_addr > b->or_addr) return 1;
+       return 0;
+}
+
+emit_relo()
+{
+       struct outrelo *ACKrelo;
+       register struct outrelo *ap;
+       unsigned int cnt = outhead.oh_nrelo;
+       long last, curr, base;
+       int sect;
+       char *bp;
+       register char *b;
+
+       ACKrelo = ap = (struct outrelo *) calloc(cnt, sizeof(struct outrelo));
+       bp = b = malloc(4 + cnt);
+       if (!ap || !bp) {
+               fatal("No memory.\n");
+       }
+       rd_relo(ap, cnt);
+       qsort((char *) ap, (int) cnt, sizeof(struct outrelo), compare);
+       /*
+         * read relocation, modify to GEMDOS format, and write.
+         * Only longs can be relocated.
+         *
+         * The GEMDOS format starts with a long L: the offset to the
+         * beginning of text for the first long to be relocated.
+         * If L==0 then no relocations have to be made.
+         *
+         * The long is followed by zero or more bytes. Each byte B is
+         * processed separately, in one of the following ways:
+         *
+         * B==0:
+         *      end of relocation
+         * B==1:
+         *      no relocation, but add 254 to the current offset
+         * B==0bWWWWWWW0:
+         *      B is added to the current offset and the long addressed
+         *      is relocated. Note that 00000010 means 1 word distance.
+         * B==0bXXXXXXX1:
+         *      illegal
+         */
+
+       last = 0;
+       curr = 0;
+       for (sect = S_MIN; sect <= S_MIN+2; sect++) {
+               base = outsect[sect-S_MIN].os_base;
+               for (;cnt > 0 && ap->or_sect == sect; ap++, cnt--) {
+                       if (ap->or_type & RELPC ||
+                           ap->or_nami == outhead.oh_nname) {
+                               continue;
+                       }
+                       assert(ap->or_type & RELO4);
+                       curr = base + ap->or_addr;
+                       if (last == 0) {
+                               last = curr;
+                               cvlong(&curr);
+                               *((long *) b) = curr;
+                               b += 4;
+                       }
+                       else {
+                               while (curr - last > 255) {
+                                       *b++ = 1;
+                                       last += 254;
+                               }
+                               *b++ = curr - last;
+                               last = curr;
+                       }
+               }
+               assert(cnt == 0 || ap->or_sect > sect);
+       }
+       assert(cnt == 0);
+       if (cnt = (b - bp)) {
+               *b++ = '\0';
+               write(output, bp, (int) cnt+1);
+       }
+       else write(output, "\0\0\0", 4);
+       free((char *) ACKrelo);
+       free(bp);
+}
+
+long
+chmem(str, old)
+char *str;
+long old;
+{
+        register long num, new;
+        long atol();
+
+        num = atol(str+1);
+        if (num == 0)
+                fatal("bad chmem amount %s\n", str+1);
+        switch (str[0]) {
+        case '-':
+                new = old - num; break;
+        case '+':
+                new = old + num; break;
+        case '=':
+                new = num; break;
+        }
+        return(new);
+}
+
+cvlong(l)
+       long *l;
+{
+       long x = *l;
+       char *p = (char *) l;
+
+       *p++ = x >> 24;
+       *p++ = x >> 16;
+       *p++ = x >> 8;
+       *p = x;
+}
+
+/* VARARGS1 */
+fatal(s, a1, a2)
+       char    *s;
+{
+       fprintf(stderr,"%s: ",program) ;
+       fprintf(stderr, s, a1, a2);
+       if (outputfile_created)
+               unlink(output_file);
+       exit(-1);
+}
+
+rd_fatal() { fatal("read error.\n"); }