(*************************************************************************

     $RCSfile: HookUtil.mod $
  Description:

   Created by: fjc (Frank Copeland)
    $Revision: 3.2 $
      $Author: fjc $
        $Date: 1994/08/08 16:11:09 $

  Copyright © 1994, Frank Copeland.
  This file is part of the Oberon-A Library.
  See Oberon-A.doc for conditions of use and distribution.

*************************************************************************)

MODULE HookUtil;

(*
** $C- CaseChk       $I- IndexChk  $L+ LongAdr   $N- NilChk
** $P- PortableCode  $R- RangeChk  $S- StackChk  $T- TypeChk
** $V- OvflChk       $Z- ZeroVars
*)

IMPORT E := Exec, U := Utility, SYS := SYSTEM;

(*------------------------------------*)
(*
  This procedure is intended to be installed in the entry field of a
  U.Hook record.  Its purpose is to push the parameters passed to it
  onto the stack and call the procedure installed in the subEntry field.

  The parameters are:

    hook    : U.HookPtr; (* passed in the A0 register *)
    object  : E.APTR;    (* passed in the A2 register *)
    message : E.APTR;    (* passed in the A1 register *)

  Stack checking should be turned off ($S-) in all procedures installed
  in Hooks, as they are likely to be running in a non-Oberon context.
*)

(* $r- Suppress RETURN check *)
PROCEDURE HookEntry* () : E.APTR;

BEGIN (* HookEntry *)
  SYS.INLINE (
    2F08H,                       (* MOVE.L A0, -(A7)      *)
    2F0AH,                       (* MOVE.L A2, -(A7)      *)
    2F09H,                       (* MOVE.L A1, -(A7)      *)
    2068H, 000CH,                (* MOVE.L  000C(A0), A0  *)
    4E90H                        (* JSR    (A0)           *)
    )                            (* RTS                   *)
  (*
    No RETURN is required, result is already in D0.
    Compiler automatically generates RTS.
    The procedure in subEntry will clean up the parameters on the stack.
  *)
END HookEntry;

(*------------------------------------*)
PROCEDURE InitHook *
  (VAR hook : U.Hook; subEntry : U.HookFunc; data : E.APTR);

BEGIN (* InitHook *)
  hook.entry := HookEntry;
  hook.subEntry := subEntry;
  hook.data := data;
END InitHook;

END HookUtil.
