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