dgee@cup.portal.com (David O Goodman) (01/05/89)
Recently, in article <12879@cup.portal.com>, I inquired: > Does anyone have suggestions for a graceful way in which to pass the > address of a ZCPR 3.x environment descriptor to a program written in a > high level language, so that the program can make use of the various ZCPR > facilities? Specifically, rather than hard-wiring the environment > descriptor address into the program, thus making it non-portable, what > would be a good way for a utility written in bds-c to learn the > environment descriptor address? > ... > Any ideas, suggestions, or further discussion would be appreciated. If I > receive mail on this subject, I will summarize to the net. Most of the comments received were public postings, so I won't quote them extensively. Apparently, according to the collective wisdom of the net, there is no formal mechanism for passing a pointer to the environment descriptor (ENV) to a program written in an HLL. Should such a mechanism exist? More on that latter. Several different approaches were mentioned, some of which were generally applicable to any language, and some of which were peculiar to bds-c. I. Find the environment descriptor by searching memory for the identifying string 'Z3ENV'. Marc Wilson (mwilson@crash.cts.com) in <3649@crash.cts.com> wrote: > The *easiest* way is to code a loop that begins at the top of memory > and scans downwards for the string "Z3ENV". As long as you're between the > BIOS and the top of memory, the only place that that string should appear > is at address ENV+3. That'll give you the environment address. > > Note that this technique is *extremely* dangerous on any system that > supports memory-mapped I/O ( i.e. Apple CP/M ), for obvious reasons. Both Jay Sage (SAGE@LL.ARPA) and Bridger Mitchell (bridger%rcc@RAND.ORG) pointed out that a simple memory search is not sufficient, since 'Z3ENV' could exist at other locations than the ENV, (named directory buffer, disk i/o buffers, etc). They mentioned that if this technique is used, a check should be made to be sure the ENV address indicated by the search agrees with the self-contained address at ENV+1Bh. I used this technique several years ago for a few programs, but finally rejected it because it is not bulletproof. As Marc Wilson mentioned, the search can produce very interesting results on any system with memory mapped i/o; that alone seems sufficient reason to reject it for any program meant for general distribution. II. Write a module, perhaps ASM or a C structure, which mimics the z3env header, then jumps to the runtime package entry point; link this module in at the correct address. Several good folks from whom I received mail suggested this approach. The catch, of course, is linking such a module at the correct address. I don't see that one has that option. I'm no authority on HLLs as run under cp/m, but since the final binary must start execution at 100h, would not a designer place the runtime package/initialization code at that address? III. Compile and link in the usual way; hand patch the final binary by moving the first few bytes (where the Z3 header goes) to the end of the file, together with a mover routine. Patch a Z3 header in the space thus left at the beginning. At run time, pick up the ENV pointer from the header, store it at some fixed location, move the first few bytes back to the beginning of the file, and jump to the beginning. This ingenious idea came from Bridger Mitchell (bridger%rcc@RAND.ORG). It is certainly generally applicable, not only to bds-c, but to any .COM file. The only negative is the rather kludgy way in which the final binary must be put together, but even that could be automated, as Bridger points out, with a ZEX script. IV. Incorporate a Z3 header in CCC.ASM, the source code for the bds-c runtime package. Assemble to a customized runtime package (C.CCC) to be used with ZCPR. Andrew Scott Beals (bandy@well.UUCP) in <10150@well.UUCP> wrote: > Have my eyes been deceiving me? > > Everyone who owns a [legal] copy of BDS C knows that you get the source to > "C.CCC", which is the run-time header that gets prepended to all .COM > programs. The solution is to simply take Bridger's code (jmp 10bh ! db > 'ZENV3',1 ! dw 0) and put it at the head of the source to C.CCC ... No, Andy, your eyes haven't been deceiving you! And yes, I own a legal copy of bds-c! Andy's suggestion makes a lot of sense, though it is applicable to bds-c only, and is not a general solution to the problem of Zcpr/HLLs. It was also my first tentative solution to the problem, before posting my inquiry. It can perhaps be done, but it is not quite as simple as Andy suggests, and has a few disadvantages. According to the documentation (I haven't actually tried this, yet), and without going into excessive detail, that part of the standard library which is written in C would have to be recompiled, using a new standard header which accorded with the new C.CCC. That part of the library written in assembly language would have to be reassembled, as most such functions reference absolute addresses in the runtime package. So, now we have a second, non-standard set of libraries and a second, non-standard runtime package, different files with identical names, and we must remember to get the right pieces of the right package when we put it all together at 4:00 AM! Also, the linker (CLINK) plugs certain information into absolute addresses in C.CCC. This can be worked around by using various linker options; unfortunately using those options deprives us of the possibility of using the -n (no warm boot) option, which allows the application to simply 'return' rather than warm booting. Nevertheless, this could work for bds-c. Without getting into a debate on the side-issue of assembly language vs high-level language programming for cp/m, a few thoughts come to mind. Cp/m has come a long way since plain vanilla cp/m 2.2, and offers many more advanced facilities. The environment descriptor is fundamental to making use of these facilities. If we were designing the operating system from scratch, no doubt the environment descriptor address would be available from a system call. This could not be done when we had only the Digital Research bdos. Now, however, we have a whole new generation of bdos replacements being used in our 'Z' systems. Would it not be appropriate to consider incorporating a system call which returns a pointer to ENV in these new bdos's? -- Dave Goodman dgee@cup.portal.com ...sun!portal!cup.portal.com!dgee