Subject: Re: Dynamic Loadable Segments?
From: [email-masked] (David Empson)
Date: Mon, 21 Mar 1994 13:38:21 GMT
Newsgroups: comp.sys.apple2.programmer

In article <[email-masked]>, Joe Busnengo  <[email-masked]> wrote:
> Would it be possible to create a modular program that would load its own
> segments off disk when it needed them, but not load them unless a
> call was made by the program?

That is exactly how standard dynamic segments work (in the IIgs Object
Module Format, as used by GS/OS applications, shell EXE files, NDAs,
CDAs, INITs, etc.)  This will work for any of the aforementioned file
types, assuming GS/OS is active.  I wouldn't recommend using dynamic
segments in a CDA, for example.  You also cannot use them in code
resources (such as CDEVs or XCMDs), or in code which has been detached
from a program (a technique sometimes used by INITs).

In ORCA/C, you can declare a dynamic segment by using the statement:

segment "other", dynamic;

(Replace "other" by the name you want to use for the segment.)  This
line should be placed before the function (or functions) which are to
go in the dynamic segment.  All subsequent functions go into the
dynamic segment.  If you want to switch back to a static segment, use:

segment "main";

Use whatever name you like for "main".  The ORCA/C library functions
and your global variables in the small model are in a segment with a
blank name; I suspect you can use

segment "";

to select the blank segment explicitly.

You can use the segment directive in either memory model.

Note that each code segment (static or dynamic) is limited to 64k of
code.  You cannot put variables into another segment - they always go
in the blank segment.  In the large memory model, arrays and
structures go into their own segment, which can be larger than 64k.

Once you have declared a dynamic segment, it will automatically be
loaded when you call any of the functions in that segment.  This can be
dangerous, especially if you're out of memory - there is no way to
recover from an error during an automatic load of a dynamic segment.

To get around this, you can pre-load the segment when you're about to
call it, by calling LoadSegName with the name specified in the segment
directive.  You can deal with errors at this point, and if the segment
was loaded OK, call the contained functions at will.

[By the way: try to avoid using LoadSegNum.  LoadSegName is much safer,
particularly if you start adding segments to your program, or use
ExpressLoad.]

Once the segment is loaded, it will stay in memory until your program
quits, unless you unload it (using UnloadSeg).  You should keep track
of which (if any) functions from the segment are currently in use.

There is an excellent technical note explaining how to use Dynamic
Segments.  See TN.IIGS.022.

> For instance, let's say that someone had a text editor.  If
> they chose the dictionary icon it would load (using LoadSegName) the
> dictionary segment off of the disk.  How would the text editor call
> the function that opens the dictionary window?  (Let's call it
> DictMain)  Would you do a 'jmp' to the address of that function?  How
> would one find the address of that function? 

Just JSL to it, as normal.  When your program is first loaded (prior
to any dynamic segments being loaded), all the JSLs to dynamic
segments are pointing into the "jump table", which contains a JMP to
the segment loading routine in the System Loader.  When the dynamic
segment gets loaded, the jump table is patched to point to the actual
routines.  All this is transparent to your application, and the
patching occurs whether you let the segment be loaded automatically, or
load it yourself using LoadSegName.

If you want to set up a dynamic segment in an assembly language
program, use the following (from ORCA):

ObjSegName START LoadSegName
           KIND  $8000              ; Dynamic code segment

           ...

           END

All object segments which are to go in the dynamic segment must use
the same LoadSegName.  To be on the safe side, you should also specify
KIND $8000 for each one.

Only JSL instructions are allowed to refer to dynamic segments from
outside the segment.  I think you'll get a linker error if you try to
make any other kind of reference.

The code in a dynamic segment should be able to make any type of
reference to labels declared inside that segment (or in any static
segment of the program).  They can also call other dynamic segments
(via JSL - same rules as for the static segments of the program).

For further information, see TN.IIGS.022 and the GS/OS Reference Manual,
particularly the chapter on the System Loader toolset and the appendix
describing Object Module Format (at least the part on segment types
and the jump table segment).

Good luck!
-- 
David Empson
[email-masked]
Snail mail: P.O. Box 27-103, Wellington, New Zealand