papa@bacall.UUCP (Marco Papa) (01/03/87)
Since I finally got overlays to work with ALL versions of Lattice C and with the latest beta MANX, I decided to put together this little tutorial on how to use overlays, so that other people do not have to spend endless hours trying to figure this out. 1. Lattice C (actually Alink) overlays. Two days ago I got the "alink"-compatible set of libraries that will work with Lattice C 3.10. These are currently needed for anybody that wants to use overlays with Lattice C 3.10, since BLINK does not yet support them (any word from the Software Distillery?). I basically was the first one that needed them, so they created these for me. If you have Lattice C 3.10, and need to use overlays NOW, you should call them and they'll send you a disk with 5 files: three sets of libraries (that substitute lc, lcm and lcmffp), and a new startup file in object and source form (that substitute c.o and c.a). These libraries are compiled without the pc-relative option, and therefore are compatible with Alink. Linking went fine. Unfortunately file size went down only of 4K (out of 150K). The big gain with Lattice C 3.10 comes when using PC-relative addressing, but at the moment that and overlays do not go together, until BLINK is fixed. 2. Undocumented "unloadseg" in MANX C Today I got a great (undocumented) fix from Gary Shultz of MicroIllusions (the makers of Dynamic-CAD). Overlays in MANX work differently than when using Alink and ovs-20 with Lattice C. With Alink overlays in parallel branches of the overlay tree are mutually exclusive, and when a new overlay is loaded, the parallel overlay gets AUTOMATICALLY unloaded (an UnloadSeg is done by the overlay handler). This has the benefit of transparency to the C source code, since the overlay info is only in the linker WITH file. On the other hand, it limits the type of overlays to a tree structure (see the description in the AmigaDOS Developers Manual). In MANX 3.30x (c, d or e) overlays are supported, but the overlay structure is not restricted to a tree. On the other hand, overlays are NOT AUTOMATICALLY unloaded, but one has to call a particular routine. The 3.20A docs (page tech.5) tell you that one should use the function UnloadSeg to unload a MANX overlay. NOOOOO! Using UnloadSeg (with uppercase U and capital S) calls the AmigaDos function and will bomb your system. You should instead call unloadseg (with lowercase u and s) with the name of a routine in the overlay that you want unloaded (it does not matter which one) as the only parameter. For example, in my own program A-Talk, I have 6 different terminal emulators. Each one is in a separate overlay, since one uses only one emulator at a time. The code looks like this: int (*emulate)(); /* a var that will invoke the emulator output function */ int OutputVT100(); /* the output functions */ int OutputH19(); int OutputVT52(); int OutputANSI(); int OutputTTY(); int OutputTalk(); int OutputTek(); int InputVT100(); /* the input functions */ etc... LoadNewEmulator(whichone) /* this routine unloads the old emulator and loads the new one */ { ... #ifdef MANX /* only needed for MANX */ if (!firsttime) unloadseg(emulate); #endif switch (whichone) { case VT100: emulate = OutputVT100; /* this loads the new overlay */ /* in both MANX and Lattice */ keyboard = InputVT100; break; case H19: emulate = OutputH19; keyboard = InputH19; break; /* the same for all other emulators/overlays */ .... } } OutChars(buffer,n) /* this one outputs/translates input chars depending on the emulators conventions */ { ... (*emulate)(buffer, n); ... } Now the code that goes in one of the overlays: OutputVT100(buf,n) { ... } InputVT100(buf,n) { ... } Note that "unloadseg" should NOT be called the first time, since the overlay might not be loaded yet. Again, thanks to Gary for the "incorrectly-documented" feature. I hope this will save somebody a headache. -- Marco Papa Felsina Software