****************************************************************************
*
*    $RCSfile: OberonSysMOVE.asm $
* Description: Runtime support for the Oberon-A compiler
*
*  Created by: fjc (Frank Copeland)
*   $Revision: 1.2 $
*     $Author: fjc $
*       $Date: 1994/05/12 20:31:15 $
*
* Copyright © 1994, Frank Copeland.
* This file is part of the Oberon-A Library.
* See Oberon-A.doc for conditions of use and distribution.
*
* Log entries are at the end of the file.
*
****************************************************************************
*
* This file contains the MC68000 source code for part of the runtime
* support library of the Oberon-A compiler.  It contains the code to
* implement the Oberon standard procedure SYSTEM.MOVE ().
*
* Other parts of the runtime system may be found in the other files in
* this directory.  The object files resulting from assembling these
* files are concatenated to create OberonSys.lib.
*
**********************************************************************

;---------------------------------------------------------------------
;    Program unit hunk name

     TTL OberonSys

;---------------------------------------------------------------------
;    Imports  (sort of ...)

ABSEXECBASE    EQU  4     ; The only absolute memory address in the
                          ; Amiga OS.  Contains a pointer to the base
                          ; of the Exec system library.

CopyMem        EQU  -624  ; Offset of the CopyMem () function from the
                          ; base of the Exec library.

;---------------------------------------------------------------------

     ;----------------------------------------------------------------
     ; PROCEDURE OberonSys_MOVE (
     ;   src {A0} : LONGINT;
     ;   dst {A1} : LONGINT;
     ;   len {D0} : LONGINT)
     ;
     ; This procedure is called by the compiler when it translates a
     ; call to SYSTEM.MOVE ().  In this initial implementation, it
     ; sends non-overlapping blocks to the Exec function CopyMem ()
     ; and handles overlapping blocks with a simple byte copy from
     ; high memory to low.
     ;
     ; Algorithm
     ;
     ; BEGIN
     ;   IF (src = dst) OR (len <= 0) THEN RETURN END;
     ;   IF (dst > src) & (dst < (src + len)) THEN
     ;     (* The blocks overlap, so copy bytes from the *top* down *)
     ;     INC (src, len); INC (dst, len);
     ;     REPEAT
     ;       DEC (src); DEC (dst);
     ;       Mem [dst] := Mem [src];
     ;       DEC (len)
     ;     UNTIL len = 0
     ;   ELSE
     ;     (* Non-overlapping blocks, let CopyMem() do it. *)
     ;     Exec.CopyMem (src, dst, len)
     ;   END;
     ; END OberonSys_MOVE;
     ;
     ; Register use
     ;
     ;   A0, A1 & D0 are used to pass parameters.  They match the
     ;   parameters needed by Exec.CopyMem(), so they are left
     ;   undisturbed until it is certain Exec.CopyMem() will not be
     ;   called. D1 is used as a temporary.
     ;
     ;   All these registers are considered scratch by the compiler,
     ;   so they do not need to be saved.
     ;
     ;----------------------------------------------------------------

     SECTION OberonSys,CODE   ; The linker will merge this hunk with
                              ; all the others with the same name.

     XDEF      OberonSys_MOVE ; Export the procedure name so the
                              ; linker can see it.

OberonSys_MOVE:

     CMPA.L    A1,A0     ; IF (src = dst) THEN RETURN
     BEQ.S     3$
     TST.L     D0        ; IF (len <= 0) THEN RETURN
     BLE.S     3$

     CMPA.L    A0,A1     ; IF (dst > src)
     BLE.S     2$
     MOVE.L    A0,D1     ;   (D1 <- src + len)
     ADD.L     D0,D1
     CMPA.L    D1,A1     ; & (dst < (src + len)) THEN
     BGE.S     2$

     MOVE.L    D1,A0     ;   INC (src, len) (src + len already in D1)
     ADDA.L    D0,A1     ;   INC (dst, len)
1$                       ;   REPEAT
     MOVE.B    -(A0),-(A1);    DEC (src); DEC (dst);
                         ;     Mem[dst] := Mem[src]
     SUBQ      #1,D0     ;     DEC (len)
     BGT.S     1$        ;   UNTIL len = 0
     BRA.S     3$
2$                       ; ELSE
     MOVE.L    ABSEXECBASE,A6
     JSR       CopyMem(A6);  Exec.CopyMem (src, dst, len)
3$                       ; END
     RTS

;---------------------------------------------------------------------

     END  ; OberonSys

****************************************************************************
*
* $Log: OberonSysMOVE.asm $
* Revision 1.2  1994/05/12  20:31:15  fjc
* - Prepared for release
*
* Revision 1.1  1994/01/15  18:31:52  fjc
* Start of revision control
*
* (12 Jan 1994) Modified to assemble with PhxAss instead of A68K
*
****************************************************************************

