README.TXT for neccessary manual conversions to be done, when porting
           a V3.4 program to V4.0
TERRA Datentechnik, Tech Support                             27-Mar-92/Bj
-------------------------------------------------------------------------


1. Changes Due to Modifications in the Run-Time System Structure
----------------------------------------------------------------

- The overall structure of the run-time system has changed, i.e., modules
  RTSMain, DebugPMD no longer exist, and their functionality has been moved
  to other modules.

- The procedure HALT no longer stops the program producing a dump, but just
  terminates the program normally.

Thus all modules that import these modules have to be changed accordingly.

!!!!  The following list just shows some examples of these modifications,
!!!!  and is NOT a complete list of all these changes!



Some procedures from V3.4 RTSMain:

       3.40: RTSMain.Terminate          ->   4.00: RTSTerm.Terminate
       3.40: RTSMain.Status             ->   4.00: RTSTypes.Status
       3.40: RTSMain.InstallTermProc    ->   4.00: RTSTerm.InstallTermProc


To make the RTS produce a dump in case of run-time errors now import MED:

       3.40: DebugPMD                   ->   4.00: MED

To replace the V3.4 functionality of HALT, producing a dump, all calls to
HALT have to be replaced by:

       3.40: HALT                       ->   4.00: MED.MEDDump(1)


NOTE: The module MED and its usage is described in the debugger manual
      chapter 3 'Preparing Your Program for Debugging'



2. Replace Wrong SYSTEM.DOSCALL Conversions
-------------------------------------------

M2CONVRT does not correctly translate DOSCALLs below 10H, and these have to
be corrected (the call to the procedure as well as its import):

     3.40 original code:
       SYSTEM.DOSCALL( 02Ch, CX, DX );

     M2CONVRT produces:
       DosCall_2Ch( CX, DX );

     4.00 requires:
       DosCall_02Ch( CX, DX );



3. Stronger Compatibility Rules Applied
---------------------------------------

The V4.0 Compiler is more restrictive with respect to the allowed operations
on certain types, and on expression/assignment compatibility.
This may result in compiler error messages that did not appear with V3.4.

Two examples of what is no longer accepted are:

 - Comparison of procedure variables is not allowed:

           VAR
             p1, p2 : PROC;

     3.40: IF( p1 = p2 ) THEN ...

     has to be replaced by:

     4.00  IF( ADDRESS(p1) = ADDRESS(p2) ) THEN ...


 -   3.40: allows     WriteText(myText, -SIZE( myText ));
     4.00: requires   WriteText(myText, -INTEGER(SIZE( myText )));

     with     PROCEDURE WriteText(txt : ARRAY OF CHAR; len : WORD);



4. CODE Statements
------------------

Unfortunately the CODE statement has completely disappeared from Modula-2 4.0.

Since its usage was convenient and frequent, there will be quite some modules
that are not convertible into V4.0 modules quite as easy as the rest.

Basically there are three kinds of applications for CODE statements in a
Modula-2 program, and accordingly three ways to replace them.


- Saving and restoring of modified registers before and after software
  interrupt calls.
  These can be replaced by introducing a procedure using the ALTERS attribute
  which tells the compiler to generate the neccessary PUSH / POP operations.

       3.40:  CODE (PushES);
              SWI (DOSInterrupt);
              CODE (PopES);

       has to be replaced by:

       4.00:  PROCEDURE InterruptDOS (VAR regs: REGISTERS) [ ALTERS(ES) ];
              BEGIN
                INT (DOSInterrupt, regs);
              END InterruptDOS;



- Setting and retrieving of register contents for the functions called by
  a software interrupt call.
  For this functionality, a type SYSTEM.REGISTER has been introduced, that
  provides the possibility to set the values of any register or the flags,
  and then pass them along with SYSTEM.INT (replacing V3.4 SWI).


       3.40: PROCEDURE IsKeyPressed (): BOOLEAN;
             VAR Flags : BITSET;
             BEGIN
                SETREG (AX,0100H);
                SWI (16H);
                CODE   (09CH);                (* PUSHF  We want the flags *)
                CODE   (058H);                (* POP AX *)
                GETREG (AX,Flags);
                RETURN NOT (6 IN Flags);      (* ZF is Bit 6 *)
             END IsKeyPressed;

       has to be replaced by:

       4.00: PROCEDURE IsKeyPressed (): BOOLEAN;
             VAR Reg: SYSTEM.REGISTER;
             BEGIN
                Reg.AX := 0100H;
                INT( 16H, Reg );
                RETURN NOT (6 IN Reg.FLAGS);  (* ZF is Bit 6 *)
             END IsKeyPressed;



- Assembler programming inside a Modula-2 module, i.e. some code sequences
  that cannot be done in Modula-2, and where the effort to include a proper
  Assembler module was too big (or for very old modules, not possible).

  These CODE statements now have to be translated into "real" Assembler
  statements, and put into an Assembler module.

  We provide you with examples for two methods that will show you how to
  generate an Assembler module out of the V3.4 OBJ-file. Both methods are
  straightforward, but nevertheless require some understanding of entry/exit
  and parameter passing conventions for procedures, and of Assembler
  programming.

  In any case, before starting to translate any "CODE module" into an Assembler
  module, study the module to be translated carefully, and try to split it
  into a CODE part and a Modula-2 part, i.e., make two modules with the CODE
  part imported by the Modula-2 part. Thus the amount of code to be translated
  is much easier to understand and maintain.

  See sub-directories CODE1 and CODE2 for details on the transformation methods.

  Sub-directory CODE3 shows another way to make a V3.4 CODE-module usable by
  V4.0. It does mix the two compilers V3.4 and V4.0, and prepares a module in
  a way that makes it possible to compile it with V3.4 and link it with V4.0.

