home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * LIBREF.C
- *
- * LIBREF [cmdfile]
- * (default func.def)
- */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <local/typedefs.h>
-
- #define FLIST struct _FLIST
-
- FLIST {
- MNODE Node;
- uword RegMask;
- uword IsAsm;
- char FName[64];
- };
-
- extern char *MToS();
-
- char LibGlob[64] = { "SomeUnknownLibBase" };
- char MName[128] = { "ram:MakeLib.c" };
- char LName[128] = { "ram:LinkTag.asm" };
- char TName[128] = { "ram:LibTag.asm" };
- char LibName[128] = { "ram:Lib.lib" };
- MLIST FBase;
-
- main(ac,av)
- char *av[];
- {
- FILE *fi;
- char *file = "func.def";
- char buf[128];
-
- puts("LIBREF V1.00 Sept 1988, (c)Copyright 1988 Matthew Dillon, All Rights Reserved");
- puts(" source/executable Freely distributable for non-profit only. May be USED");
- puts(" in-house to generate commercial libraries.");
-
- NewList(&FBase);
- if (ac == 2)
- file = av[1];
- fi = fopen(file, "r");
- if (!fi) {
- printf("%s not found\n", file);
- puts("LIBREF [cmdfile]");
- exit(1);
- }
- while (fgets(buf, sizeof(buf), fi)) {
- buf[strlen(buf)-1] = 0;
- if (!buf[0] || buf[0] == ';')
- continue;
- switch((buf[0]<<8)|buf[1]) {
- case '1=':
- sscanf(buf+2, "%s", MName);
- break;
- case '2=':
- sscanf(buf+2, "%s", LName);
- break;
- case '3=':
- sscanf(buf+2, "%s", TName);
- break;
- case '4=':
- sscanf(buf+2, "%s", LibGlob);
- break;
- case '5=':
- sscanf(buf+2, "%s", LibName);
- break;
- case '6=':
- case '7=':
- case '8=':
- case '9=':
- break;
- default:
- scanfile(buf, buf, sizeof(buf));
- break;
- }
- }
- fclose(fi);
- {
- FILE *fi = fopen(MName, "w");
- if (!fi) {
- printf("Unable to open %s for write\n", MName);
- exit(-1);
- }
- GenerateMakeLib(fi);
- fclose(fi);
- fi = fopen(TName, "w");
- if (!fi) {
- printf("Unable to open %s for write\n", MName);
- exit(-1);
- }
- GenerateTags(fi);
- fclose(fi);
- GenerateLinkLib(LName, strlen(LName));
- }
- }
-
- /*
- * scan file for functions
- *
- * *FUNC=NAME REGS (C, assembly tag entry, add extra _)
- * ;FUNC=NAME REGS (assembly, direct entry)
- * D0-2/A0/A1/A2 ...
- * REGISTERS ALWAYS LOADED D0-D7,A0-A7 (A6,A7 cannot be used)
- *
- * starting within the first 16 lines of the file.
- */
-
- scanfile(file, buf, bufsize)
- char *file;
- char *buf;
- long bufsize;
- {
- FILE *fi;
- short i;
-
- fi = fopen(file, "r");
- if (!fi) {
- printf("Unable to open file %s\n", file);
- return(-1);
- }
- for (i = 0; i < 16; ++i) {
- short isasm;
- short j;
- if (fgets(buf, bufsize, fi) == NULL)
- return(0);
- for (j = 0; buf[j] == ' ' || buf[j] == 9; ++j);
- isasm = (buf[j] == ';' || buf[j] == 'A');
- ++j;
- if (strncmp(buf+j, "FUNC=", 5) == 0) {
- i = 0;
- AddFunction(buf+j+5, isasm);
- }
- }
- fclose(fi);
- }
-
- /*
- * FuncName Regs (NULL SPECIAL)
- */
-
- AddFunction(buf, isasm)
- char *buf;
- {
- char fname[64];
- char regs[64];
- uword regmask = 0; /* A7-A0,D7-D0 */
-
- if (sscanf(buf, "%s %s", fname, regs) != 2) {
- printf("Argument Error: %s\n", buf);
- return(-1);
- }
- if (strcmp(regs, "-") == 0)
- regs[0] = 0;
- {
- register short i;
- register short s, e;
- for (i = 0; regs[i]; ) {
- s = e = regs[i+1] - '0';
- if (s < 0 || s > 7)
- goto fail;
- switch(regs[i]) {
- case 'A':
- s += 8;
- e += 8;
- i += 2;
- if (regs[i] == '-') {
- if (regs[i+1] != 'A')
- goto fail;
- e = regs[i+2] - '0';
- if (e < 0 || e > 7)
- goto fail;
- e += 8;
- i += 3;
- }
- break;
- case 'D':
- i += 2;
- if (regs[i] == '-') {
- if (regs[i+1] != 'D')
- goto fail;
- e = regs[i+2] - '0';
- if (e < 0 || e > 7)
- goto fail;
- i += 3;
- }
- break;
- default:
- goto fail;
- }
- while (s <= e) {
- regmask |= 1 << s;
- ++s;
- }
- if (regs[i]) {
- if (regs[i] != '/')
- goto fail;
- ++i;
- }
- }
- }
- /*
- printf("Function: %-10s Regs: %04x Asm: %d\n", fname, regmask, isasm);
- */
- {
- register FLIST *fl = malloc(sizeof(FLIST));
- if (fl) {
- fl->RegMask = regmask;
- fl->IsAsm = isasm;
- if (strcmp(fname, "NULL") == 0)
- fl->FName[0] = 0;
- else
- strcpy(fl->FName, fname);
- AddTail(&FBase, fl);
- }
- }
- return(0);
- fail:
- printf("Bad Register Spec: %s\n", buf);
- return(-1);
- }
-
- GenerateMakeLib(fi)
- FILE *fi;
- {
- register FLIST *fl;
- short i;
-
- fprintf(fi, "\n/*\n * Machine Generated Library Vectors\n */\n\n");
- fprintf(fi, "#ifndef NULL\n#define NULL 0L\n#endif\n\n");
- fprintf(fi, "extern long _LibOpen(), _LibClose(), _LibExpunge();\n");
- for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
- if (fl->FName[0]) {
- if (fl->IsAsm) { /* If assembly, direct reference */
- fprintf(fi, "extern long l%s();\n", fl->FName);
- } else { /* If not, reference to tag */
- fprintf(fi, "extern long _l%s();\n", fl->FName);
- }
- }
- }
-
- fprintf(fi, "\n\n/*\n * -30-6*X\n */\n\n");
- fprintf(fi, "long (*LibVectors[])() = {\n");
- fprintf(fi, " _LibOpen, _LibClose, _LibExpunge, NULL,\n\n");
- for (i = 0, fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
- if (fl->FName[0]) {
- if (fl->IsAsm)
- fprintf(fi, " l%-16s, /* %3ld %-20s */\n", fl->FName, -30-6*i, MToS(fl->RegMask));
- else
- fprintf(fi, " _l%-15s, /* %3ld %-20s */\n", fl->FName, -30-6*i, MToS(fl->RegMask));
- } else {
- fprintf(fi, " NULL,\n");
- }
- ++i;
- }
- fprintf(fi, " (long (*)())-1\n};\n\n");
- }
-
- GenerateTags(fi)
- FILE *fi;
- {
- register FLIST *fl;
-
- fprintf(fi, "\n");
- fprintf(fi, "\t; Machine Generated File\n");
- fprintf(fi, "\t; Tags for library routines which are in C\n\n");
- fprintf(fi, "\tFAR\tDATA\n\n");
- for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
- uword mask;
- if (fl->IsAsm || !fl->FName[0])
- continue;
- fprintf(fi, "\n");
- fprintf(fi, "\t\tpublic _l%s\n\t\tpublic __l%s\n\n", fl->FName, fl->FName);
- fprintf(fi, "__l%s:\n", fl->FName);
-
- /*
- * Save the set D2/D3/A6, but don't bother saving D2 or
- * D2 and D3 if passed as arguments.
- */
-
- mask = 0x400C;
- MoveToStack(fi, mask); /* Save some args */
- MoveToStack(fi, fl->RegMask); /* Push some args */
- fprintf(fi, "\t\tbsr\t_l%s\n", fl->FName);
- PopStack(fi, fl->RegMask);
- MoveFromStack(fi, mask);
- fprintf(fi,"\t\trts\n");
- }
- }
-
-
- /*
- * Generate the link library. Create N output modules for
- * each function reference by appending a number to the name
- */
-
- GenerateLinkLib(dir, dirlen)
- char *dir;
- short dirlen;
- {
- char tmp[128];
- short i, nobj, nj;
- FILE *fi;
- FILE *fi2;
- register FLIST *fl;
- register short off;
-
- strcpy(dir+dirlen, "Makefile");
- fi = fopen(dir, "w");
- if (!fi)
- goto fail;
- strcpy(dir+dirlen, "Ordin");
- fi2 = fopen(dir, "w");
- if (!fi2)
- goto fail;
-
- fputs("\nAFLAGS = -D\n\n", fi);
-
- nj = 0;
- nobj = 1;
- for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
- if (!fl->FName[0])
- continue;
- fprintf(fi2, "%s.o\n", fl->FName);
- if (nj == 0)
- fprintf(fi, "OBJ%d = ", nobj);
- fprintf(fi, "%s.o ", fl->FName);
- nj += strlen(fl->FName) + 3;
- if (nj > 70) {
- fprintf(fi, "\n");
- nj = 0;
- ++nobj;
- }
- }
- fprintf(fi2, "lvo.o\n");
- if (nj == 0)
- fprintf(fi, "OBJ%d = ", nobj);
- fprintf(fi, "lvo.o\n");
- fclose(fi2);
- fprintf(fi, "\nall:\t");
- for (i = 1; i <= nobj; ++i) {
- fprintf(fi, "$(OBJ%d) ", i);
- }
- fprintf(fi, "\n");
- fprintf(fi, "\tord %s ", dir);
- strcpy(dir+dirlen, "Ordout");
- fprintf(fi, "\t%s\n", dir);
- fprintf(fi, "\t-Delete %s\n", LibName);
- fprintf(fi, "\tlb %s -f %s\n", LibName, dir);
-
- strcpy(dir+dirlen, "lvo.asm");
-
-
- fclose(fi);
- fi = fopen(dir, "w");
- if (!fi)
- goto fail;
- for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
- if (fl->FName[0])
- fprintf(fi, "\t\tpublic\t_LVO%s\n", fl->FName);
- }
- for (off = -30, fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
- if (!fl->FName[0]) {
- off -= 6;
- continue;
- }
- sprintf(tmp, "_LVO%s", fl->FName);
- fprintf(fi, "%-24s\tequ\t%d\n", tmp, off);
- off -= 6;
- }
- fclose(fi);
-
- for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
- if (!fl->FName[0])
- continue;
- strcpy(dir+dirlen, "TEMP");
- strcpy(tmp, dir);
-
- strcpy(dir+dirlen, fl->FName);
- strcat(dir+dirlen, ".asm");
- fi = fopen(tmp, "w");
- if (!fi)
- goto fail;
-
- fprintf(fi,"\n; Machine Generated Link Tag\n\n");
- fprintf(fi,"\t\tFAR\tDATA\n");
- fprintf(fi,"\t\tpublic\t_LVO%s\n", fl->FName);
- fprintf(fi,"\t\tpublic\t_%s\n", LibGlob);
- fprintf(fi,"\t\tpublic\t_%s\n\n", fl->FName);
- fprintf(fi,"_%s:\n", fl->FName);
-
- /*
- * Generate linker tag to assembly. If neither A0 or A1 is
- * used as an argument, use one as the link register, else
- * save A6 and use that.
- *
- * If A2-A6 (inc A6 above), D2-D6 are required to hold
- * parameters, they are saved before the call, restored
- * after. If they are not required to hold any parameters,
- * a JMP is issued instead of a JSR.
- */
-
- {
- uword argmask = fl->RegMask;
- uword savmask = fl->RegMask;
- short areg = 6;
- if (!(argmask & 0x0100)) /* A0 not used */
- areg = 0;
- if (!(argmask & 0x0200)) /* A1 not used */
- areg = 1;
- savmask |= 1 << (areg+8); /* Add register usage */
- MoveToStack(fi, savmask & 0xFCFC); /* save some regs */
- LoadFromStack(fi, argmask, 4+Offset(argmask & 0xFCFC)); /* load params */
- fprintf(fi,"\t\tmove.l\t_%s,A%d\n", LibGlob, areg);
- if (savmask & 0xFCFC) {
- fprintf(fi, "\t\tjsr\t_LVO%s(A%d)\n", fl->FName, areg);
- MoveFromStack(fi, savmask & 0xFCFC); /* restore some regs */
- fprintf(fi,"\t\trts\n");
- } else {
- fprintf(fi, "\t\tjmp\t_LVO%s(A%d)\n", fl->FName, areg);
- }
- }
- fclose(fi);
- if (cmp_file(tmp, dir) == 0) { /* update only if changed */
- DeleteFile(dir);
- Rename(tmp, dir);
- }
- }
- return(0);
- fail:
- printf("Unable to open %s\n", dir);
- return(-1);
- }
-
- char *
- MToS(mask)
- register uword mask;
- {
- register short i;
- register short j = 0;
- static char buf[64];
-
- for (i = 0; i < 8; ++i, mask >>= 1) {
- if (mask & 1) {
- if (j)
- buf[j++] = '/';
- buf[j++] = 'D';
- buf[j++] = i + '0';
- }
- }
- for (i = 0; i < 8; ++i, mask >>= 1) {
- if (mask & 1) {
- if (j)
- buf[j++] = '/';
- buf[j++] = 'A';
- buf[j++] = i + '0';
- }
- }
- buf[j++] = 0;
- return(buf);
- }
-
-
- MoveToStack(fi, mask)
- FILE *fi;
- {
- char *str = MToS(mask);
- if (!str[0])
- return(0);
- if (!str[2]) {
- fprintf(fi, "\t\tmove.l\t%s,-(sp)\n", str);
- } else {
- fprintf(fi, "\t\tmovem.l\t%s,-(sp)\n", str);
- }
- }
-
- MoveFromStack(fi, mask)
- FILE *fi;
- uword mask;
- {
- char *str = MToS(mask);
-
- if (!str[0])
- return(0);
- if (!str[2])
- fprintf(fi, "\t\tmove.l\t(sp)+,%s\n", str);
- else
- fprintf(fi, "\t\tmovem.l\t(sp)+,%s\n", str);
- }
-
- LoadFromStack(fi, mask, offset)
- {
- char *str = MToS(mask);
-
- if (!str[0])
- return(0);
- if (!str[2])
- fprintf(fi, "\t\tmove.l\t%d(sp),%s\n", offset, str);
- else
- fprintf(fi, "\t\tmovem.l\t%d(sp),%s\n", offset, str);
- }
-
-
- PopStack(fi, mask)
- FILE *fi;
- uword mask;
- {
- register short j;
- if (j = Offset(mask)) {
- if (j > 8)
- fprintf(fi,"\t\tadd.w\t#%d,A7\n", j);
- else
- fprintf(fi,"\t\taddq.l\t#%d,A7\n", j);
- }
- }
-
- Offset(mask)
- uword mask;
- {
- register short i, j;
- for (i = j = 0; i < 16; ++i) {
- if (mask & (1 << i))
- ++j;
- }
- return(j*4);
- }
-
- cmp_file(name1, name2)
- char *name1;
- char *name2;
- {
- short i, fd1, fd2;
- static char buf1[1024];
- static char buf2[1024];
-
- fd1 = open(name1, O_RDONLY);
- if (fd1 < 0)
- return(0);
- fd2 = open(name2, O_RDONLY);
- if (fd2 < 0) {
- close(fd1);
- return(0);
- }
- while ((i = read(fd1, buf1, sizeof(buf1))) > 0) {
- if (read(fd2, buf2, i) != i)
- goto fail;
- if (bcmp(buf1, buf2, i) == 0)
- goto fail;
- }
- if (read(fd2, buf2, 1) != 0)
- goto fail;
- close(fd1);
- close(fd2);
- return(1);
- fail:
- close(fd1);
- close(fd2);
- return(0);
- }
-
-