ýcTZ33M2 MOD°°Z33-TM2 DOC DhZ33M2 DEF$˛”Z33M2 Z80% U˙ ˙ ˙ MODULE TZ33M2; (* TEST ZCPR33-MODULA2 INTERFACE MECHANISM *) FROM INOUT IMPORT OpenOutput,WriteHex; FROM Z33M2 IMPORT GETENV; VAR C: CARDINAL; BEGIN C :=GETENV(); OpenOutput(""); WriteHex(C,4); END TZ33M2.  The fact that ZCPR 3.3 puts the ENV address in HL before loading a program (of course Z33 also installs that program if it is determined to be a z33 program) enables us at last to be able to create Turbo Modula 2 programs that can access the myriad features of the Z-system. We are still not all the way there, it is still something of a kludge, but it is possible at last. How, you ask, is this accomplished? Doesn't TM2 grab the immediate bytes after 100H for its own uses, precluding the familiar JP START DB "Z3ENV",0 DW Z3EADR START: program structure by which Z3 utilities have traditionally communicated with their environment? You are right, but as we mention above z33 ALSO finds the ENV address and puts it in HL as the new program is loaded. This provides an ALTERNATE method by which programs can get the ENV address, which then makes possible all the advanced features of Z3 (now Z33). So then it should be a simple matter of getting the HL register before anything else is done and storing it away somewhere and we have it. Well, it ain't that simple, unfortunately. TM2 runs off to do its own initialization code before anything you write gets executed, and modules created from assembler can't have initialization code. So where does that leave us? Fortunately it is still pretty easy to get around this, but you have to patch .COM files to do it. Not the prettiest, but it works. What are the tools in this library that enable this? Just a skeleton module that does nothing but store this address away for program use and a test module so that you can see it works. Z33M2.Z80 -- the assembler code to grab the ENV at the start of the program. Also code for a procedure which takes this address and gives it back to the Modula code for use there. Z33M2.DEF -- the interface for the above procedure to M2. TZ33M2.MOD -- a test module which calls on the Module InOut to print the ENV in HEX. If we know enough to print it, we know enough to use it. Instructions: -- 1>ASSEMBLE Z33M2.Z80 with M80,ZAS, or Z80asm to a .REL file INVOKE M2 2>ompile Z33M2.DEF 3>un REL Z33M2 Z33M2 This creates the file Z33M2.MCD 4>ompile TZ33M2.MOD 5>ink TZ33M2 TZ33M2.COM -- when asked to include all modules say yes. 6> uit M2. 7> Using ZPATCH or similar patcher on TZ33M2.COM make a note of the address in the two bytes at 101H and 102H. Write these down. Then Search for the string "Z33ENV". This has been inserted in the assembler code for just this purpose. ZPATCH will report an address where the string is found. Exactly 10-11 bytes further on there is an address which should be patched with the address you found at 101-102H. That is if the address that the search found is 2000H then at 200AH patch the same byte you found at 101H and at 200BH patch the byte you found at 102H. Now go back to 101-102H and patch here the address at which the search reported its find plus six. That is, in this example 2006H (low byte first). So at 101H we patch the value 06 and at 102H we patch the value 20. Of course the real addresses will vary, but that is all there is to it. All we have done is to redirect program execution from the code it would normally execute first to our little routine which stores HL in memory before it is destroyed. Then we jump to where TM2 would have started execution. OK, I got you started. Now who is going to put together the first useful module using this concept? The Z33M2 module can be expanded to include more useful procedures to be accessed by M2. A TCAP module could be easily built. how about something like Z3FILES which could resolve named directory references before passing control to the FILES module. What about a shell? Error handler? A program to manipulate the multi-command line buffer? Sky's the limit! Steve Cohen June 8, 1987 Z33 andler? A program to manipulate the multi-command line buffer? Sky's the limit! Steve CoDEFINITION MODULE Z33M2; PROCEDURE GETENV():CARDINAL; END Z33M2. ; skeleton of a module that gets the address of the ZCPR33 ; environmental descriptor from the command processor, and ; stores it away. Also a routine to retrieve it later, ; accessible from Turbo-Modula2. ; ; Steve Cohen ; June 8, 1987 ; PUBLIC GETENV DB 'Z33ENV' ; JUST FOR FINDING THIS CODE WITH ; PATCHER OR DEBUGGER ; this is the routine to which a program will jump (after ; we patch it to do so) immediately upon execution which ; saves the ENV address which Z33 provides us in HL. LD (Z33ADR),HL ; PATCH FIRST JUMP INSTRUCTION TO ; JUMP TO HERE JP 0 ; PATCH THIS JUMP TO WHERE THE ; OLD FIRST JUMP INSTRUCTION ; JUMPED TO Z33ADR: DW 0 ; STORAGE FOR Z33 ENV ADDRESS ; ; this routine can be called by any TM2 module that imports ; to return the ENV address. The procedure is in this form: ; ; PROCEDURE GETENV():CARDINAL; ; GETENV: LD HL,(Z33ADR) ; MUST HAVE BEEN PREVIOUSLY INITIALIZED EX (SP),HL ; RETURN IT VIA STACK PUSH HL ; put return address back RET ENDMUST HAVE BEEN PREVIOUSLY INITIALIZED EX (SP),HL ; RETURN IT VIA STACK PU