Newsgroups: comp.sys.apple2.programmer Path: news.weeg.uiowa.edu!news.uiowa.edu!hobbes.physics.uiowa.edu!math.ohio-state.edu!usc!elroy.jpl.nasa.gov!swrinde!sgiblab!munnari.oz.au!comp.vuw.ac.nz!actrix!dempson From: dempson@actrix.gen.nz (David Empson) Subject: Re: Dynamic Loadable Segments? Message-ID: Organization: Actrix Information Exchange References: <5e4u4fO.dsoft@delphi.com> Date: Mon, 21 Mar 1994 13:38:21 GMT Lines: 113 In article <5e4u4fO.dsoft@delphi.com>, Joe Busnengo 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 dempson@actrix.gen.nz Snail mail: P.O. Box 27-103, Wellington, New Zealand