TERRA Datentechnik, Technical Support Sheet        Rev. 0,  29-May-92
---------------------------------------------------------------------
A. Gorrengourt


Startup and Termination in Logitech/MultiScope Modula-2 Release 4.00
--------------------------------------------------------------------

All of the following relates to the medium model under DOS. Other
memory models and environments have not really been investigated.

Notation: For symbol names that do not follow the standard Modula-2
conventions (i.e. symbol name # <module name>_<procedure/variable name>)
both names are given. Modula-2 names are enclosed in double quotes and
symbols names are enclosed in single quotes.


1. Startup

The program entry point is at the BEGIN of the body of the main module.

Code generated by compiler for "BEGIN" of main module body:
       XOR     BP, BP             ; set BP to 0 for debugger
       PUSH    BP                 : bottom of call chain (BP chain)
       MOV     BP, SP
       CALL    FAR 'SYSTEM_Start' ; (no corresponding Modula-2 name)

Note 1: 'SYSTEM_Start' is provided by RTSSTART.ASM (public symbol),
but is not explicitly exported from/declared in RTSSTART.DEF.

Note 2: RTSSTART.ASM also contains a public symbol 'SYSTEM_StartSmall',
which seems to be used in the case of a small model program.

'SYSTEM_Start':
Among other things 'SYSTEM_Start'sets DS to the DGROUP and stores
its return address (i.e. the address of the instruction following
the call to it in the body of the main module) in the variable
"RTSStart.mainProgEntryPoint". It reduces the size of the memory
block allocated to the program by the DOS loader to the minimum needed,
stores the PSP pointer in "RTSMain.cmdLinePtr", calls
"RTSUtil.SetActiveProcess" to establish the active process, and finally
calls "RTSMain.ModulaEntry".

"RTSMain.ModulaEntry":
First initializes some variables (e.g. "blocklist", "deviceMask",
main program descriptor). Saves and sets up the interrupt vectors
used. Calls "RTSExec.Execute", passing "RTSStart.mainProgEntryPoint".

"RTSExec.Execute":
Initializes the process descriptor passed. Stores the current SP, SS,
and BP in the program descriptor passed. These are intended to be used
(restored) upon termination (see note below). Performs a call to the
entry point passed, i.e. transfers control to the code in the body of
the main module.

Note: When the SP, SS, and BP saved by "Execute" are restored, the next
return instruction will cause execution to continue at the point where
"Execute" was called, i.e. after that call in "RTSMain.ModulaEntry". 


2. Termination

2.1. Termination when Reaching the End of the Main Module Body 

Code generated by compiler for "END" of main module body:
       MOV     AX, 0000          ; "Normal" status
       PUSH    AX                ; push parameter
       CALL    FAR 'SYSTEM_HALT' ; = "Error.DoHalt"

"Error.DoHalt" = 'SYSTEM_HALT':
Converts the CARDINAL parameter to type "RTSTypes.Status" and calls
the local procedure "Exception". The zero value passed by the compiler
for the call at the end of the main module body results in status
"Normal", i.e. in normal termination.

"Error.Exception" (not exported):
If parameter status >= Halt then exception info (i.e. code address of
exception) is put into a global variable of this module and its address
is stored in the descriptor of the current process. If an exception
handler has been installed it is called, otherwise the default exception
handler "RTSExcep.ExceptionHandler" is called.

"RTSExcep.ExceptionHandler":
If no "writeMessage" procedure has been installed for the current
process, "Error.DefaultWriteMessage" is now installed. The parameter
status is stored in the "progStatus" field of the program descriptor.
Finally calls "RTSExec.TerminateExecution".

Note: As it seems, the field "programStatus" of the process descriptor
is not set or used anywhere in the V4 RTS and library sources.

"RTSExec.TerminateExecution":
This procedure is defined to terminate the execution of the parent
program to which the current Modula-2 process belongs. It stores the
pointer to the terminating process in the global variable
"ptTerminatedProcess", calls the installed termination procedures,
and then calls "RTSExecSub.ExitTerminate", passing the SS and BP
saved in the program descriptor by "RTSExec.Execute" upon startup.

"RTSExecSub.ExitTerminate":
Re-establishes the stack SS:SP to the SS:BP paramter passed, pops
BP, and returns. The return goes to "RTSMain.ModulaEntry", i.e. to
the routine that called "RTSExec.Execute" which saved SS, SP and BP.

"RTSMain.ModulaEntry" (continuing after call to "RTSExec.Execute"):
Restores the old interrupt controller mask and the old interrupt
vectors. Gets the terminating process from "RTSExec". If the program
status indicates "Normal", returns with the "errorCode". Otherwise
the (if installed) the "writeMessage" procedure is called and an
error code of 1 (progStatus < Fatal) or 2 (progStatus >= Halt) is
returned.

The return goes to the end of 'SYSTEM_Start' (RTSSTART.ASM), which
exits to DOS returning that error code.

2.2. Termination by Run-Time Error

Procedures of module "Error":
The run-time check code generated by the compiler contains calls to
the corresponding error procedures provided by module "Error":
"StackOvf" = 'SYSTEM_StackOverflow', "RangeErr" = 'SYSTEM_RangeError',
etc.  All these error procedures call the local procedure "Exception",
passing an appropriate status value. From there termination/exception
handling continues as described above.

2.3. Termination by Calling the Modula-2 Standard Procedure HALT

"Error.DoHalt (0)" = 'SYSTEM_HALT (0)':
The standard procedure HALT is translated to "Error.DoHalt (0)" =
'SYSTEM_HALT (0)'. Like the other error procedures, "DoHalt" calls
the local procedure "Exception", passing its parameter converted to
the corresponding status value (i.e. "Normal" for the zero passed
in case of HALT). From there termination/exception handling continues
as described above. Because the zero value passed by the compiler in
case of HALT is translated to status "Normal", calling the standard
procedure HALT results in normal termination without any special
message.

2.4. Termination by Calling "RTSTerm.Terminate"

"RTSTerm.Terminate":
Sets the program status as indicated and calls "RTSExec.TerminateExecution".
From there termination continues as described above. As it can be seen
from the notes above, usually no message will be displayed, because no
one takes care to install the default "writeMessage" procedure.

                              * * *
