home *** CD-ROM | disk | FTP | other *** search
- (***************************************************************)
- (* Copyright 1987 by Edward Jackson. This program is released *)
- (* into the public domain and may be freely distributed by *)
- (* others in commercial or non-comercial situations provided *)
- (* proper credit is given to the author. *)
- (* *)
- (* M2Z3INS version 1. *)
- (* *)
- (* This program "installs" Turbo Modula2 programs which have *)
- (* been linked into .COM files in a ZCPR3 environment, ZCPR3.3 *)
- (* environment, or CP/M environment. This is accomplished by *)
- (* patching the GetEnv procedure which MUST be included in the *)
- (* root segment of the TM2 .COM file. A subsequent call to *)
- (* this procedure will return the address of the resident *)
- (* environment descriptor or, for CP/M, a NIL address and a *)
- (* string of up to 16 characters. The string is intended to *)
- (* be used as a file name for TCAP information but can be used *)
- (* for any other purpose desired. *)
- (* *)
- (* In a ZCPR3 environment the address of the environment *)
- (* descriptor is obtained from the *.ENV file that is peculiar *)
- (* to the target system. *)
- (* *)
- (* In a ZCPR3.3 environment the address of the environment *)
- (* descriptor is placed in register HL by the loader after *)
- (* loading the .COM file. The .COM file is patched by this *)
- (* installation program so that register HL is saved in the *)
- (* GetEnv procedure. *)
- (* *)
- (* In a CP/M environment there is no environment descriptor *)
- (* so this instalation program patches the environment des- *)
- (* criptor address to NIL and the 16 char string to the value *)
- (* specified at installation time. *)
- (* *)
- (* NOTES: Where an environment descriptor is available, the *)
- (* 16 char string is empty. *)
- (* *)
- (* Since many ZCPR systems place the environmen des- *)
- (* criptor at 0FE00h, this is used as the default *)
- (* value in GetEnv. *)
- (* *)
- (* Special thanks to Steve Cohen for sugesting the basic *)
- (* approach. *)
- (***************************************************************)
-
- MODULE M2Z3INS1;
- FROM STORAGE IMPORT ALLOCATE;
- FROM InOut IMPORT WriteHex;
- FROM SYSTEM IMPORT ADDRESS,
- FILL,
- ADR;
- FROM ComLine IMPORT PromptFor;
- FROM Files IMPORT FILE,
- ReadBytes,
- ReadByte,
- WriteBytes,
- WriteByte,
- SetPos,
- NextPos,
- Open,
- Close,
- EOF;
- FROM Strings IMPORT Append,
- Pos,
- Length,
- CAPS,
- Delete;
- FROM Terminal IMPORT ReadChar;
-
- CONST Version = 1; (* Version number *)
-
- EXCEPTION FileErr;
- TYPE
- SysType = (CPM, Z3, Z33);
- VAR
- EnvName, Tm2Name : ARRAY [0..15] OF CHAR;
- TCAPName : ARRAY [0..15] OF CHAR;
- Environment,
- Tm2File : FILE;
- EnvAdr : POINTER TO ADDRESS;
- InstallType : CHAR;
- Nbytes, i : CARDINAL;
- TestStr, Target : ARRAY [0..6] OF CHAR;
- Switch : SysType;
- OK : BOOLEAN;
- c : CHAR;
- C : ARRAY [0..0] OF CHAR;
- SwitchStr : ARRAY [0..2] OF CHAR;
- EnvAdrLoc,
- JmpBackLoc,
- TCAPFNLoc,
- InstallTypeLoc : LONGINT;
- JmpToAdr,
- JmpBackAdr : POINTER TO CARDINAL;
-
- BEGIN
- (* Sign on legend *)
- FOR i := 1 TO 24 DO
- WRITELN ();
- END;
- WRITELN (' TM2/ZCPR3 Installation Program');
- WRITELN (' Copyright 1987 by Edward Jackson, Gilroy, CA');
- WRITELN (' Released into the Public Domain by the Author');
- WRITELN ();
- WRITELN ('Version ', Version:1);
- WRITELN ();
- WRITELN
- (' Patches .COM files generated by Turbo Modula2 so that the');
- WRITELN
- (' address of the resident environment descriptor is available');
- WRITELN
- (' for use by the program in a ZCPR3 or ZCPR3.3 system. For');
- WRITELN
- (' CP/M systems, a 16 char file name is patched in for use as');
- WRITELN
- (' desired.');
- WRITELN ();
- WRITELN (' Press any key to continue... ');
- WRITELN (); WRITELN (); WRITELN (); WRITELN ();
- ReadChar (c);
-
- NEW (EnvAdr);
- NEW (JmpToAdr);
- NEW (JmpBackAdr);
-
- (* Get target system type *)
- PromptFor ("Patch for CP/M, ZCPR3 or ZCPR3.3? [C, 3 or 3.3] ", SwitchStr);
- IF SwitchStr = "C" THEN
- Switch := CPM;
- ELSIF SwitchStr = "3" THEN
- Switch := Z3;
- ELSIF SwitchStr = "3.3" THEN
- Switch := Z33;
- ELSE
- WRITELN ("Invalid system designation!");
- HALT;
- END;
-
- FILL (ADR (TCAPName), 16, 0);
-
- (* get the arguments required for the target system type *)
- IF Switch = Z3 THEN
- PromptFor ("Enter name of Environment Descriptor File: ", EnvName);
- PromptFor ('Enter name of TM2 "COM" file to be installed: ', Tm2Name);
- CAPS (EnvName);
- ELSIF Switch = CPM THEN
- PromptFor ('Enter 16 character name of TCAP file: ', TCAPName);
- CAPS (TCAPName);
- PromptFor ('Enter name of TM2 "COM" file to be installed: ', Tm2Name);
- ELSE
- PromptFor ('Enter name of TM2 "COM" file to be installed: ', Tm2Name);
- END;
-
- (* do some error checking on the arguments *)
- CAPS (Tm2Name);
- IF Pos (".COM", Tm2Name) <> (Length (Tm2Name) - 4) THEN
- WRITELN ('Can only install "COM" files.');
- HALT;
- END;
-
- IF Switch = Z3 THEN
- OK := Open (Environment, EnvName);
- IF NOT OK THEN
- WRITELN ("Can't find environment file!");
- HALT;
- END;
- END;
-
- OK := Open (Tm2File, Tm2Name);
- IF NOT OK THEN
- WRITELN ("Can't find TM2 file!");
- HALT;
- END;
-
- (* Search for "Z3.3ENV" string in the .COM file *)
- (* It is embedded in the GetEnv procedure *)
- SetPos (Tm2File, 7000L); (* start near end of TM2 Run Time routines *)
- TestStr := '';
- Target := 'Z3.3ENV';
-
- LOOP
- IF EOF (Tm2File) THEN (* "Z3.3ENV" not found *)
- WRITELN ("Can't install this program");
- Close (Tm2File);
- HALT;
- END;
-
- (* Read a char at a time and add to test string. If test string length > 0 *)
- (* and a partial match is not found at front of string, discard the first *)
- (* char in test string and continue. EXIT Loop when test string = *)
- (* "Z3.3ENV" *)
- ReadByte (Tm2File, c);
- C [0] := c;
- Append (C, TestStr);
- WHILE (Length (TestStr) > 0) AND (Pos (TestStr, Target) <> 0) DO
- Delete (TestStr, 0, 1);
- END;
- IF TestStr = Target THEN
- EXIT;
- END
- END;
-
- (* record important locations in Tm2File *)
- EnvAdrLoc := NextPos (Tm2File);
- JmpToAdr^ := CARD (EnvAdrLoc) + 19 + 256; (* corrected for load at 100h *)
- JmpBackLoc := EnvAdrLoc + 23L;
- InstallTypeLoc := EnvAdrLoc + 18L;
- TCAPFNLoc := EnvAdrLoc + 2L;
-
- (* save current jumpback address *)
- SetPos (Tm2File, JmpBackLoc);
- Nbytes := ReadBytes (Tm2File, JmpBackAdr, 2);
- IF Nbytes <> 2 THEN
- RAISE FileErr;
- END;
-
- (* Get current installation type (0 = CPM, 1 = ZCPR3, 2 = ZCPR3.3) *)
- SetPos (Tm2File, InstallTypeLoc);
- ReadByte (Tm2File, InstallType);
-
-
- (* If current install type ZCPR3.3 then must unpatch first *)
- IF InstallType = 2C THEN
- SetPos (Tm2File, 1L);
- WriteBytes (Tm2File, JmpBackAdr, 2);
- END;
-
- (* Always set the TCAP File name buffer with nulls if target not CP/M *)
- SetPos (Tm2File, TCAPFNLoc);
- WriteBytes (Tm2File, ADR (TCAPName), 16);
-
- (* If target is ZCPR3 Get Environment descriptor address from *.ENV file *)
- IF Switch = Z3 THEN
- SetPos (Environment, 27L);
- Nbytes := ReadBytes (Environment, EnvAdr, 2);
- Close (Environment);
-
- IF Nbytes <> 2 THEN
- RAISE FileErr;
- END;
-
- WRITE ('Environment Descriptor Address is: ');
- WriteHex (CARDINAL (EnvAdr^), 0);
- WRITELN ();
-
- (* Patch the .COM file for target system = ZCPR3 *)
- SetPos (Tm2File, EnvAdrLoc);
- WriteBytes (Tm2File, EnvAdr, 2);
- InstallType := CHR (ORD (Switch)); (* Mark as installed for ZCPR3 *)
- SetPos (Tm2File, InstallTypeLoc);
- WriteByte (Tm2File, InstallType);
-
- ELSIF Switch = CPM THEN
- EnvAdr^ := 0;
-
- (* Patch the .COM file for target system = CP/M *)
- SetPos (Tm2File, EnvAdrLoc);
- WriteBytes (Tm2File, EnvAdr, 2);
- InstallType := CHR (ORD (Switch)); (* Mark as installed for CP/M *)
- SetPos (Tm2File, InstallTypeLoc);
- WriteByte (Tm2File, InstallType);
-
- ELSE
-
- (* Patch the .COM file for target system = ZCPR3.3 *)
- SetPos (Tm2File, 1L);
- Nbytes := ReadBytes (Tm2File, JmpBackAdr, 2);
- IF Nbytes <> 2 THEN
- RAISE FileErr;
- END;
- SetPos (Tm2File, InstallTypeLoc); (* mark target system type *)
- InstallType := CHR (ORD (Switch));
- WriteByte (Tm2File, InstallType);
- SetPos (Tm2File, 1L);
- WriteBytes (Tm2File, JmpToAdr, 2); (* Patch to code that saves HL *)
- SetPos (Tm2File, JmpBackLoc);
- WriteBytes (Tm2File, JmpBackAdr, 2); (* Patch return Tm2 Init code *)
- WRITELN ();
- WRITELN (Tm2Name, ' is now patched so that the Environment Descriptor');
- WRITELN ('will be saved inside the GetEnv procedure when the file is');
- WRITELN ('loaded by ZCPR3.3');
- END;
-
- Close (Tm2File);
-
- WRITELN ();
- WRITELN ('Installation complete.');
-
- EXCEPTION
- | FileErr : Close (Tm2File);
- WRITELN ('Error reading Tm2 file');
- HALT;
-
- END M2Z3INS1.
-