INSTALL -- Version 1.0 -- 25 March 1987
Hi/Lo memory module relocation package
by Shane Dawalt [71076,511]

Copyright information
---------------------

     INSTALLS/CMD, INSTALLS/ASM and INSTALL/TXT are copyrighted 1987 by Shane
Dawalt. INSTALL/ASM and INSTALL/REL are released to public domain by the
author.


Introduction
------------

     This package includes INSTALL/ASM, INSTALL/REL, INSTALLS/CMD and
INSTALLS/ASM (source code for INSTALLS/CMD) in addition to this documentation.
INSTALL/ASM is an assembly language module which may be INCLUDEd into your
source code (the assembler directives *INCLUDE and *GET may be used in the MRAS
assembler, other assemblers may require different directives).  INSTALL/REL is
provided if your program requires a linker (or you like to library modules).
INSTALLS/CMD is an assembled program which installs/removes the INSTALL SVC
module.  INSTALLS/ASM is the source code for INSTALLS/CMD.  This provides a
working example of how to use the INSTALL/ASM module in a program.  To keep
relocation painless between all INSTALL modules available, data passing
procedures are exactly the same for all.


Passing Data
------------

Data to be passed to all INSTALL modules are placed in registers HL, BC, D and
IX.  The data and registers used are identified below:

        HL = Address of module to relocate.
        BC = Number of bytes in module to relocate.
        IX = Address of relocation table.  This table contains a pointer
             to each address to relocate.  The table is terminated with a
             word of value 0.  If your module doesn't have a relocation
             table, IX must be set to 0.
         D = Memory flag: 0 = low memory, any other value = high memory.

When the INSTALL module returns, it supplies the following flags/data to the
calling program.

        If Z flag, operation successful:
             HL = Relocated address of the first byte of the module.
             DE = Relocated address of the last byte of the module.
        If NZ flag then:
             If using D = 0, insuffecient memory for low memory area
                   installation.
             If using D <> 0, changing of HIGH$ is inhibited by $CFLAGS.

Registers HL, DE, BC and AF are destroyed.

     If your application is installing a module into memory using a Standard
TRSDOS Memory Header please refer to SPECIAL INFORMATION below for important
information regarding the usage of memory headers and INSTALL.  This applies
to the INSTALL/ASM/REL and the INSTALL SVC modules.


Usage as an INCLUDE file
------------------------
(Instructions for MRAS only, other assemblers may differ.)

     Place the "INCLUDE INSTALL" directive in the source code where INSTALL is
to be included at.  Set the registers to the appropriate values as dictated
above and "CALL INSTALL".  That's it!  The registers/flags will be returned as
dictated above.


Usage as a REL file
-------------------
(Instructions for MRAS only, other assemblers may differ.)

     Place "EXTRN INSTALL" (or "EXT INSTALL") pseudo-OP at the beginning of
your source which will use the INSTALL/REL file.  Where INSTALL is to be
invoked, simply place a "CALL INSTALL" instruction.  Assemble your source as a
relocatable file and link your source, INSTALL/REL and any other REL file
required.  That's it!


Usage as an SVC
---------------

     TO USE THIS OPTION, THE DOS VERSION MUST BE 6.2.0 OR HIGHER.  INSTALLS
WILL CHECK THE SYSTEM FOR THE VERSION NUMBER BEFORE ANY SVC GENERATING IS DONE.
IF A VERSION LOWER THAN 6.2.0 IS RUNNING INSTALLS WILL ABORT.

     Heretofor, INSVC implies the module placed in memory by INSTALLS.  This
naming convention will become more clear later on.

     INSTALL is less than 200 bytes long, so an SVC module isn't out of the
question.  An SVC module can be used by applications without actually having
the relocation module be part of the application.  INSVC may be SYSGENed
(which will keep the assigned SVC slot allocated) or INSTALLS may be executed
via JCL.  If INSVC is already resident & linked to the system, INSTALLS will
abort without claiming extra memory.  If INSVC isn't resident at all, a module
will be generated and placed in high memory.  At the conclusion of
installation, INSTALLS will display the currently allocated SVC slot inwhich
INSVC is linked to plus the address at which INSVC was relocated and the
number of bytes used by INSVC.  Finally, if INSVC is resident but unlinked from
the system, the current module will be used instead of allocating new memory.
If relinking of a currently resident module is successful, a message will be
displayed on the screen informing the user of the slot number used.

     In any case, to install INSTALL as an SVC, type "INSTALLS {xxx}<ENTER>" at
the DOS ready prompt.  "xxx" is an optional user requested SVC slot number.
Slot numbers which are available for use are 124, 125, 126 and 127.  INSTALLS
defaults to 127 if no user SVC slot number is included.  In the event that
INSVC is alread resident but unlinked, INSTALLS will use the previous slot
number assigned to the currently resident module unless a user entered slot
number is found.

     There is a possiblity that one or more of the SVC slots may be in use by
other applications.  If INSTALLS finds that the requested or default SVC slot
is unavailable, a list of all USER SVC slots available will be displayed on the
screen.  The user will be prompted for a slot of his/her choice.  Pressing
<BREAK> at this prompt will result in INSTALLS aborting installation and
returning to DOS ready.  Slot numbers other than those displayed on the screen
are ignored.  If a JCL is executing installation will be aborted since the
user cannot gain access to the keyboard.

     To use the SVC in source code, set the registers to the appropriate values
dictated above and issue a "LD A,xxx" followed by "RST 28H", where xxx is the
slot number displayed on the screen after INSVC was installed.


Removing the SVC
----------------

     To remove INSVC from memory issue the command "INSTALLS R<ENTER>" at the
DOS ready prompt.  If other memory modules have been installed below INSVC,
INSTALLS will not be able to release the memory occupied by INSVC.  Otherwise,
INSTALLS will reset HIGH$ above INSVC thereby releasing the memory used.  In
either case, INSTALLS unlinks INSVC from the system's SVC table.  If the
memory could not be released, INSVC will stay in high memory.


********************
* IMPORTANT NOTICE *
********************

               The INSVC must be resident when a program, which uses
          the SVC, is executed.  SYSGEN may be used to keep the INSVC
          in the SVC slot allocated at installation.  If a JCL is
          used to install the INSVC after bootup, the JCL should
          explicity tell INSTALLS which SVC slot to use.

     The INSVC is generated with a standard TRSDOS Memory Header (outlined in
the Model 4 Technical Reference Manual).  This enables other programs to
interrogate the system so that residency of INSVC can be verified before
executing code which requires it.  To determine if INSVC is installed, use
@GTMOD SVC with a module name of "INSVC".  To test which SVC slot INSVC is
installed in, add 4 to the DE register returned by @GTMOD SVC -- this will
point the DE register to the SVC slot number.  The slot number is the number
which INSTALLS linked INSVC to during installation (also the slot number
displayed on the screen at the conslusion of a successful installation).


***********************
* SPECIAL INFORMATION *
***********************

               TRSDOS requires all memory modules to be fitted with a
          Memory Header.  (INSTALLS includes the memory header used
          by INSVC.)  Memory headers REQUIRE that the address of the
          last byte of the module be placed in the word starting at
          byte 2 of the memory header.  INSTALL (all versions) does
          not insert this for you.  INSTALL returns all the addresses
          required to make this task easier.  After returning from any
          INSTALL version, simply add two to HL and place the contents
          of DE (in low order hi order form) into the memory pointed
          to by HL.  (See INSTALLS source code at label "START20".)
          A simpler way to do this is to relocate the end of module
          address (see examples below).  FAILURE TO COMPLY WITH THIS
          REQUIREMENT MAY YIELD A LOCKED UP SYSTEM WHEN THE @GTMOD
          SVC IS INVOKED VIA AN APPLICATION OR SYSTEM CALL.

     If your application will not be requiring @GTMOD SVC and other
applications/DOS commands will not require @GTMOD SVC, you may leave the header
off of your module.  This will relieve you from stuffing the end of module
address.  This is the primary reason for not allowing INSTALL to automatically
place the end of module address in the header.


Other stuff
-----------

     INSTALL only relocates programs, it does not erase them.  For erasing hi
memory routines see Paul Bradshaw's UNSET program (with accompanying
documentation) in the LDOS forum DLs.  Note that the current version of UNSET
(ver 2.0) erases the most currently inserted module in HI memory only.  DO NOT
attempt to use UNSET to erase the INSVC from memory since the most current
version of UNSET (ver 2.0) cannot reset the system's SVC table to the proper
value.  For this, use the INSTALLS utility.

     The programs/modules look bug free.  If any bugs crop up, leave an email
to the author at 71076,511 or leave a message on LDOS forum *marked* to
71076,511.  Suggestions are welcome.

Shane Dawalt
CIS ID: 71076,511


===============================================================================
Examples
--------

     Below are two examples.  The examples are to describe how to set up the
registers for invokation of INSTALL, both with SVC and with CALL.  It also
indicates what to do with IX when no relocation table is used.  For a working
example, see INSTALLS source code.

Example 1, High memory installation
-----------------------------------

BEGIN	LD	HL,MOD1		;p/u module 1 absolute pointer
	LD	BC,RELOTAB-MOD1	;p/u # of bytes in module 1
	LD	D,1		;identify hi memory installation
	LD	IX,RELOTAB	;p/u pointer to relocation table
	CALL	INSTALL
	JR	Z,CONTINUE	;continue if ok
	LD	HL,ERRMSG
	SVC	@DSPLY
	SVC	@EXIT
CONTINUE	.
		.		;other code to do whatever you so desire!
		.
MOD1END	RET			;return to dos
ERRMSG	DB	'System has locked HIGH$, cannot change.',0DH
;
; Start of module
;
MOD1	JR	MOD1BEG		;goto module 1 beginning
R00	DW	MOD1END		;absolute addr of module 1
;    MOD1END is the end of module address.  This will be relocated by the
;      Relocation pointer R00.  This is an easier way of determining the end of
;      module address.  For the harder way (but required for the particular
;      code), see INSTALLS at "START20".
	DB	4		;# of bytes in name
	DB	'MOD1'
MODDCB	DW	0,0
;
; Beginning of module programming
;
MOD1BEG	OR	A		;suppose something is passed in A
	CALL	NZ,MOD1DO	;do something from mod1
R01	EQU	$-2		;don't forget a pointer for relocation
	RET			;return to caller
MOD1DO	.
	.	And this can go on and on and on ...
	.
MOD1END	RET			;return from call & mark end of module
;
; Now, relocation table
;
RELOTAB	DW	R00,R01,0	;0 marks end of table
	END	BEGIN




Example 2, low memory installation
----------------------------------

The module routine from above (MOD1) will be used in this example.  However, assume there is NO relocation table in MOD1.

BEGIN	LD	HL,MOD1		;p/u module 1 absolute pointer
	LD	BC,NO_OF_BYTES	;p/u # of bytes in module 1
	LD	D,0		;identify low memory installation
	LD	IX,0		;*** no relocation table ***
	LD	A,127		;A = slot where INSTALLS put the SVC
	RST	28H
	JR	Z,CONTINUE	;if ok, continue
	LD	HL,NOMEM
	SVC	@DSPLY
	SVC	@EXIT
NOMEM	DB	'Insuffecient memory to install module.',0DH
CONTINUE	.
	Continue with above program
