page@swan.ulowell.edu (Bob Page) (10/25/88)
Submitted-by: dillon@cory.berkeley.edu (Matt Dillon) Posting-number: Volume 2, Issue 18 Archive-name: util/dres.3 # This is a shell archive. Remove anything before this line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # This archive contains the following files: # README # core/TODO # core/funcs.reg # core/libfuncs.h # core/libtag.asm # core/Makefile # core/func.def # core/library.c # libref.c # if `test ! -s README` then echo "writing README" cat > README << '\Rogue\Monster\' The makefile is in core. CD into core and then 'make'. Make will fist compile libref.c which is used to generate the link library and library function array. \Rogue\Monster\ else echo "will not over write README" fi if [ `wc -c README | awk '{printf $1}'` -ne 163 ] then echo `wc -c README | awk '{print "Got " $1 ", Expected " 163}'` fi if `test ! -d core` then mkdir core echo "mkdir core" fi if `test ! -s core/TODO` then echo "writing core/TODO" cat > core/TODO << '\Rogue\Monster\' add dos.library to list of libraries.... \Rogue\Monster\ else echo "will not over write core/TODO" fi if [ `wc -c core/TODO | awk '{printf $1}'` -ne 43 ] then echo `wc -c core/TODO | awk '{print "Got " $1 ", Expected " 43}'` fi if `test ! -s core/funcs.reg` then echo "writing core/funcs.reg" cat > core/funcs.reg << '\Rogue\Monster\' # Q interrupts AFUNC= OpenQInts - AFUNC= CloseQInts A0 AFUNC= SetQPri D0/D1 AFUNC= SetQVector D0/D1/D2/D3/A0 AFUNC= NULL - AFUNC= NULL - AFUNC= NULL - AFUNC= NULL - # List functions AFUNC= GetHead A0 AFUNC= GetTail A0 AFUNC= GetSucc A0 AFUNC= GetPred A0 AFUNC= GetHeadOff D0/D1 AFUNC= GetTailOff D0/D1 AFUNC= GetSuccOff D0/D1 AFUNC= GetPredOff D0/D1 AFUNC= EnqueueLong D0/D1/D2/D4 AFUNC= EnqueueOffLong D0/D1/D2/D3/D4 AFUNC= SearchFwdNode D0/D1/A1 AFUNC= SearchRvsNode D0/D1/A1 AFUNC= SearchFwdList D0/D1/A1 AFUNC= SearchRvsList D0/D1/A1 AFUNC= SearchFwdNodeOff D0/D1/A0/A1 AFUNC= SearchRvsNodeOff D0/D1/A0/A1 AFUNC= SearchFwdListOff D0/D1/A0/A1 AFUNC= SearchRvsListOff D0/D1/A0/A1 AFUNC= NULL - AFUNC= NULL - AFUNC= NULL - AFUNC= NULL - # Memory functions AFUNC= BZero D0/D1 AFUNC= BSet D0/D1/A0 AFUNC= BMov D0/D1/A0 AFUNC= BCmp D0/D1/A0 AFUNC= NULL - AFUNC= NULL - AFUNC= NULL - AFUNC= NULL - # Misc. Functions AFUNC= WildCmp D0/D1 AFUNC= WaitMsg A0 AFUNC= CheckMsg A0 AFUNC= CheckPort A0 AFUNC= LockAddr A0 AFUNC= LockAddrB D0/A0 AFUNC= UnLockAddr A0 AFUNC= UnLockAddrB D0/A0 AFUNC= DoSyncMsg A0/A1 AFUNC= FindName2 D0/A0 # placed in res.c CFUNC= GetTaskData D0/D1 CFUNC= FreeTaskData D0 CFUNC= DateToS D0/D1/A0 CFUNC= SetFileDate D0/D1 CFUNC= NULL - CFUNC= NULL - CFUNC= NULL - CFUNC= NULL - # IPC functions CFUNC= OpenIPC D0/D1 CFUNC= CloseIPC D0 CFUNC= SendIPC D0/D1/D2/A0 CFUNC= SendIPC2 D0/D1 CFUNC= ReplyIPC D0/D1/D2/A0 CFUNC= FreeIPC D0 CFUNC= DoIPC2 D0/D1/D2/A0 CFUNC= ParseCmd D0/D1/D2/D3/D4/A0 CFUNC= FreeParseCmd D0 CFUNC= NULL D0 CFUNC= NULL - CFUNC= NULL - CFUNC= NULL - # Resource Library functions \Rogue\Monster\ else echo "will not over write core/funcs.reg" fi if [ `wc -c core/funcs.reg | awk '{printf $1}'` -ne 1944 ] then echo `wc -c core/funcs.reg | awk '{print "Got " $1 ", Expected " 1944}'` fi if `test ! -s core/libfuncs.h` then echo "writing core/libfuncs.h" cat > core/libfuncs.h << '\Rogue\Monster\' /* * Machine Generated Library Vectors */ #ifndef NULL #define NULL 0L #endif extern long _LibOpen(), _LibClose(), _LibExpunge(); extern long lOpenQInts(); extern long lCloseQInts(); extern long lSetQPri(); extern long lSetQVector(); extern long lGetHead(); extern long lGetTail(); extern long lGetSucc(); extern long lGetPred(); extern long lGetHeadOff(); extern long lGetTailOff(); extern long lGetSuccOff(); extern long lGetPredOff(); extern long lEnqueueLong(); extern long lEnqueueOffLong(); extern long lSearchFwdNode(); extern long lSearchRvsNode(); extern long lSearchFwdList(); extern long lSearchRvsList(); extern long lSearchFwdNodeOff(); extern long lSearchRvsNodeOff(); extern long lSearchFwdListOff(); extern long lSearchRvsListOff(); extern long lBZero(); extern long lBSet(); extern long lBMov(); extern long lBCmp(); extern long lWildCmp(); extern long lWaitMsg(); extern long lCheckMsg(); extern long lCheckPort(); extern long lLockAddr(); extern long lLockAddrB(); extern long lUnLockAddr(); extern long lUnLockAddrB(); extern long lDoSyncMsg(); extern long lFindName2(); extern long _lGetTaskData(); extern long _lFreeTaskData(); extern long _lDateToS(); extern long _lSetFileDate(); extern long _lOpenIPC(); extern long _lCloseIPC(); extern long _lSendIPC(); extern long _lSendIPC2(); extern long _lReplyIPC(); extern long _lFreeIPC(); extern long _lDoIPC2(); extern long _lParseCmd(); extern long _lFreeParseCmd(); /* * -30-6*X */ long (*LibVectors[])() = { _LibOpen, _LibClose, _LibExpunge, NULL, lOpenQInts , /* -30 */ lCloseQInts , /* -36 A0 */ lSetQPri , /* -42 D0/D1 */ lSetQVector , /* -48 D0/D1/D2/D3/A0 */ NULL, NULL, NULL, NULL, lGetHead , /* -78 A0 */ lGetTail , /* -84 A0 */ lGetSucc , /* -90 A0 */ lGetPred , /* -96 A0 */ lGetHeadOff , /* -102 D0/D1 */ lGetTailOff , /* -108 D0/D1 */ lGetSuccOff , /* -114 D0/D1 */ lGetPredOff , /* -120 D0/D1 */ lEnqueueLong , /* -126 D0/D1/D2/D4 */ lEnqueueOffLong , /* -132 D0/D1/D2/D3/D4 */ lSearchFwdNode , /* -138 D0/D1/A1 */ lSearchRvsNode , /* -144 D0/D1/A1 */ lSearchFwdList , /* -150 D0/D1/A1 */ lSearchRvsList , /* -156 D0/D1/A1 */ lSearchFwdNodeOff, /* -162 D0/D1/A0/A1 */ lSearchRvsNodeOff, /* -168 D0/D1/A0/A1 */ lSearchFwdListOff, /* -174 D0/D1/A0/A1 */ lSearchRvsListOff, /* -180 D0/D1/A0/A1 */ NULL, NULL, NULL, NULL, lBZero , /* -210 D0/D1 */ lBSet , /* -216 D0/D1/A0 */ lBMov , /* -222 D0/D1/A0 */ lBCmp , /* -228 D0/D1/A0 */ NULL, NULL, NULL, NULL, lWildCmp , /* -258 D0/D1 */ lWaitMsg , /* -264 A0 */ lCheckMsg , /* -270 A0 */ lCheckPort , /* -276 A0 */ lLockAddr , /* -282 A0 */ lLockAddrB , /* -288 D0/A0 */ lUnLockAddr , /* -294 A0 */ lUnLockAddrB , /* -300 D0/A0 */ lDoSyncMsg , /* -306 A0/A1 */ lFindName2 , /* -312 D0/A0 */ _lGetTaskData , /* -318 D0/D1 */ _lFreeTaskData , /* -324 D0 */ _lDateToS , /* -330 D0/D1/A0 */ _lSetFileDate , /* -336 D0/D1 */ NULL, NULL, NULL, NULL, _lOpenIPC , /* -366 D0/D1 */ _lCloseIPC , /* -372 D0 */ _lSendIPC , /* -378 D0/D1/D2/A0 */ _lSendIPC2 , /* -384 D0/D1 */ _lReplyIPC , /* -390 D0/D1/D2/A0 */ _lFreeIPC , /* -396 D0 */ _lDoIPC2 , /* -402 D0/D1/D2/A0 */ _lParseCmd , /* -408 D0/D1/D2/D3/D4/A0 */ _lFreeParseCmd , /* -414 D0 */ NULL, NULL, NULL, NULL, (long (*)())-1 }; \Rogue\Monster\ else echo "will not over write core/libfuncs.h" fi if [ `wc -c core/libfuncs.h | awk '{printf $1}'` -ne 4739 ] then echo `wc -c core/libfuncs.h | awk '{print "Got " $1 ", Expected " 4739}'` fi if `test ! -s core/libtag.asm` then echo "writing core/libtag.asm" cat > core/libtag.asm << '\Rogue\Monster\' ; Machine Generated File ; Tags for library routines which are in C FAR DATA public _lGetTaskData public __lGetTaskData __lGetTaskData: movem.l D2/D3/A6,-(sp) movem.l D0/D1,-(sp) bsr _lGetTaskData addq.l #8,A7 movem.l (sp)+,D2/D3/A6 rts public _lFreeTaskData public __lFreeTaskData __lFreeTaskData: movem.l D2/D3/A6,-(sp) move.l D0,-(sp) bsr _lFreeTaskData addq.l #4,A7 movem.l (sp)+,D2/D3/A6 rts public _lDateToS public __lDateToS __lDateToS: movem.l D2/D3/A6,-(sp) movem.l D0/D1/A0,-(sp) bsr _lDateToS add.w #12,A7 movem.l (sp)+,D2/D3/A6 rts public _lSetFileDate public __lSetFileDate __lSetFileDate: movem.l D2/D3/A6,-(sp) movem.l D0/D1,-(sp) bsr _lSetFileDate addq.l #8,A7 movem.l (sp)+,D2/D3/A6 rts public _lOpenIPC public __lOpenIPC __lOpenIPC: movem.l D2/D3/A6,-(sp) movem.l D0/D1,-(sp) bsr _lOpenIPC addq.l #8,A7 movem.l (sp)+,D2/D3/A6 rts public _lCloseIPC public __lCloseIPC __lCloseIPC: movem.l D2/D3/A6,-(sp) move.l D0,-(sp) bsr _lCloseIPC addq.l #4,A7 movem.l (sp)+,D2/D3/A6 rts public _lSendIPC public __lSendIPC __lSendIPC: movem.l D2/D3/A6,-(sp) movem.l D0/D1/D2/A0,-(sp) bsr _lSendIPC add.w #16,A7 movem.l (sp)+,D2/D3/A6 rts public _lSendIPC2 public __lSendIPC2 __lSendIPC2: movem.l D2/D3/A6,-(sp) movem.l D0/D1,-(sp) bsr _lSendIPC2 addq.l #8,A7 movem.l (sp)+,D2/D3/A6 rts public _lReplyIPC public __lReplyIPC __lReplyIPC: movem.l D2/D3/A6,-(sp) movem.l D0/D1/D2/A0,-(sp) bsr _lReplyIPC add.w #16,A7 movem.l (sp)+,D2/D3/A6 rts public _lFreeIPC public __lFreeIPC __lFreeIPC: movem.l D2/D3/A6,-(sp) move.l D0,-(sp) bsr _lFreeIPC addq.l #4,A7 movem.l (sp)+,D2/D3/A6 rts public _lDoIPC2 public __lDoIPC2 __lDoIPC2: movem.l D2/D3/A6,-(sp) movem.l D0/D1/D2/A0,-(sp) bsr _lDoIPC2 add.w #16,A7 movem.l (sp)+,D2/D3/A6 rts public _lParseCmd public __lParseCmd __lParseCmd: movem.l D2/D3/A6,-(sp) movem.l D0/D1/D2/D3/D4/A0,-(sp) bsr _lParseCmd add.w #24,A7 movem.l (sp)+,D2/D3/A6 rts public _lFreeParseCmd public __lFreeParseCmd __lFreeParseCmd: movem.l D2/D3/A6,-(sp) move.l D0,-(sp) bsr _lFreeParseCmd addq.l #4,A7 movem.l (sp)+,D2/D3/A6 rts \Rogue\Monster\ else echo "will not over write core/libtag.asm" fi if [ `wc -c core/libtag.asm | awk '{printf $1}'` -ne 2290 ] then echo `wc -c core/libtag.asm | awk '{print "Got " $1 ", Expected " 2290}'` fi if `test ! -s core/Makefile` then echo "writing core/Makefile" cat > core/Makefile << '\Rogue\Monster\' # Makefile for DRES.LIBRARY, AZTEC C 3.6a # # NOTE: You must have previously create the directory 'local' in your # C include's directory and placed the distribution include/local # directory there. The libref program must also have been compiled SYMS= include:symbols.m SYMC= include:local/makesymbols.c CFLAGS= +BCDLp +I$(SYMS) LREXE= srcc:libref SRC0= library.c SRC1= libtag.asm SRC2= /src/misc.c SRC3= /src/qint.asm SRC4= /src/lists.asm SRC5= /src/mem.asm SRC6= /src/timedate.c SRC7= /src/ipc.c SRC8= /src/res.c OBJ0= vd0:library.o OBJ1= vd0:libtag.o OBJ2= vd0:misc.o OBJ3= vd0:qint.o OBJ4= vd0:lists.o OBJ5= vd0:mem.o OBJ6= vd0:timedate.o OBJ7= vd0:ipc.o OBJ8= vd0:res.o OBJS= $(OBJ0) $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(OBJ6) $(OBJ7) all: $(SYMS) $(LREXE) hlib $(OBJS) ln +Q $(OBJS) -ldres -lcl32 -o libs:dres.library hlib: libref assign this: /core cd ram: make cd this: assign this: $(OBJ0): $(SRC0) cc $(CFLAGS) $(SRC0) -o $(OBJ0) $(OBJ1): $(SRC1) as $(SRC1) -o $(OBJ1) $(OBJ2): $(SRC2) cc $(CFLAGS) $(SRC2) -o $(OBJ2) $(OBJ3): $(SRC3) as $(SRC3) -o $(OBJ3) $(OBJ4): $(SRC4) as $(SRC4) -o $(OBJ4) $(OBJ5): $(SRC5) as $(SRC5) -o $(OBJ5) $(OBJ6): $(SRC6) cc $(CFLAGS) $(SRC6) -o $(OBJ6) $(OBJ7): $(SRC7) cc $(CFLAGS) $(SRC7) -o $(OBJ7) $(OBJ8): $(SRC8) cc $(CFLAGS) $(SRC8) -o $(OBJ8) $(SYMS): $(SYMC) make -f include:local/Makefile $(LREXE): /libref.c cc +L +I$(SYMS) /libref.c -o T:libref.o ln +Q T:libref.o -lsup32 -lc32 -o $(LREXE) delete T:libref.o \Rogue\Monster\ else echo "will not over write core/Makefile" fi if [ `wc -c core/Makefile | awk '{printf $1}'` -ne 1591 ] then echo `wc -c core/Makefile | awk '{print "Got " $1 ", Expected " 1591}'` fi if `test ! -s core/func.def` then echo "writing core/func.def" cat > core/func.def << '\Rogue\Monster\' ; Run Time Library Function definition file ; ; -Generate function table for MakeLibrary in C ; -Generate tags in assembly for C 1= libfuncs.h 2= ram: 3= libtag.asm 4= DResBase 5= comp:clib/dres.lib funcs.reg \Rogue\Monster\ else echo "will not over write core/func.def" fi if [ `wc -c core/func.def | awk '{printf $1}'` -ne 224 ] then echo `wc -c core/func.def | awk '{print "Got " $1 ", Expected " 224}'` fi if `test ! -s core/library.c` then echo "writing core/library.c" cat > core/library.c << '\Rogue\Monster\' /* * LIBRARY.C * * Example fully working library for Aztec C ... with comments (which is * a miracle in itself). By Matthew Dillon. PUBLIC DOMAIN. * * Aztec Compile with +BCDLp * +B No startup reference * +C Large code * +D Large data * +L 32 bit Integers * +p compatibility mode (D2/D3 preserved) * * Since Original release, the following has been fixed: * -slight bug in LibClose() .. did not expunge library if DELEXP set * on final close. (thanks to Rico Mariani for finding the bug) * -Now uses MakeLibrary call rather than a hardwired Library structure. */ #define NULL 0L typedef struct Library LIB; extern LIB *MakeLibrary(); #define VERSION 1 /* NOTE! String in dc.b below must also be */ #define REVISION 3 /* Changed! */ #asm VERSION equ 1 ; RLIB.ASM ; ; Run-time library tag FAR data public _CInit public _LibOpen public _LibClose public _LibExpunge Start: clr.l D0 rts InitDesc: dc.w $4AFC ;RTC_MATCHWORD dc.l InitDesc ;Pointer to beginning dc.l EndCode ;Note sure it matters dc.b 0 ;flags (NO RTF_AUTOINIT) dc.b VERSION ;version dc.b 9 ;NT_LIBRARY dc.b 0 ;priority (doesn't matter) dc.l _Libname ;Name of library dc.l _Libid ;ID string (note CR-LF at end) dc.l Init ;Pointer to init routine _Libname: dc.b "dres.library",0 _Libid: dc.b "dres.library 1.3 (29 Sep 1988)",13,10,0 EndCode: Init: move.l A6,-(sp) ;Must save A6 move.l A0,-(sp) ;Segment list jsr _CInit addq.l #4,sp move.l (sp)+,A6 rts cifc macro move.l D0,-(sp) ;Make a C call and save A6 to boot move.l A6,-(sp) jsr \1 move.l (sp)+,A6 addq.l #4,sp rts endm __LibOpen: cifc _LibOpen __LibClose: cifc _LibClose __LibExpunge: cifc _LibExpunge #endasm extern char Libname[1]; extern char Libid[1]; LIB *Lib, *DResBase; /* Library Base pointer */ long Seglist; /* Save the DOS seglist */ /* * The Initialization routine is given only a seglist pointer. Since * we are NOT AUTOINIT we must construct and add the library ourselves * and return either NULL or the library pointer. Exec has Forbid() * for us during the call. * * If you have an extended library structure you must specify the size * of the extended structure in MakeLibrary(). */ #include "libfuncs.h" LIB * CInit(segment) { extern long SysBase; extern long DOSBase; SysBase = *(long *)4; DOSBase = OpenLibrary("dos.library", 0); if (DOSBase == NULL) return(NULL); DResBase = Lib = MakeLibrary(LibVectors,NULL,NULL,sizeof(LIB),NULL); Lib->lib_Node.ln_Type = NT_LIBRARY; Lib->lib_Node.ln_Name = Libname; Lib->lib_Flags = LIBF_CHANGED|LIBF_SUMUSED; Lib->lib_Version = VERSION; Lib->lib_Revision = REVISION; Lib->lib_IdString = (APTR)Libid; Seglist = segment; AddLibrary(Lib); return(Lib); } /* * Open is given the library pointer and the version request. Either * return the library pointer or NULL. Remove the DELAYED-EXPUNGE flag. * Exec has Forbid() for us during the call. */ LIB * LibOpen(lib,version) LIB *lib; { ++lib->lib_OpenCnt; lib->lib_Flags &= ~LIBF_DELEXP; return(lib); } /* * Close is given the library pointer and the version request. Be sure * not to decrement the open count if already zero. If the open count * is or becomes zero AND there is a LIBF_DELEXP, we expunge the library * and return the seglist. Otherwise we return NULL. * * Note that this routine never sets LIBF_DELEXP on its own. * * Exec has Forbid() for us during the call. */ LibClose(lib) LIB *lib; { if (lib->lib_OpenCnt && --lib->lib_OpenCnt) return(NULL); if (lib->lib_Flags & LIBF_DELEXP) return(LibExpunge(lib)); return(NULL); } /* * We expunge the library and return the Seglist ONLY if the open count * is zero. If the open count is not zero we set the DELAYED-EXPUNGE * flag and return NULL. * * Exec has Forbid() for us during the call. NOTE ALSO that Expunge * might be called from the memory allocator and thus we CANNOT DO A * Wait() or otherwise take a long time to complete (straight from RKM). * * Apparently RemLibrary(lib) calls our expunge routine and would * therefore freeze if we called it ourselves. As far as I can tell * from RKM, LibExpunge(lib) must remove the library itself as shown * below. */ LibExpunge(lib) LIB *lib; { extern long DOSBase; if (lib->lib_OpenCnt) { lib->lib_Flags |= LIBF_DELEXP; return(NULL); } if (DOSBase) { CloseLibrary(DOSBase); DOSBase = NULL; } Remove(lib); FreeMem((char *)lib-lib->lib_NegSize, lib->lib_NegSize+lib->lib_PosSize); return(Seglist); } \Rogue\Monster\ else echo "will not over write core/library.c" fi if [ `wc -c core/library.c | awk '{printf $1}'` -ne 4923 ] then echo `wc -c core/library.c | awk '{print "Got " $1 ", Expected " 4923}'` fi if `test ! -s libref.c` then echo "writing libref.c" cat > libref.c << '\Rogue\Monster\' /* * 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); } \Rogue\Monster\ else echo "will not over write libref.c" fi if [ `wc -c libref.c | awk '{printf $1}'` -ne 12306 ] then echo `wc -c libref.c | awk '{print "Got " $1 ", Expected " 12306}'` fi echo "Finished archive 3 of 3" # if you want to concatenate archives, remove anything after this line exit -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.