(* ==================================================================== *)
(* === NEPHTHYS Module Library ======================================== *)
(* ==================================================================== *)
(*

  :Program.     VBR.MOD
  :Contents.    support for 68010+ VBR (vector base) register

  :Author.      Peter Fröhlich [phf]
  :Copyright.   Public Domain. Use and abuse.

  :Language.    Oberon (revised)
  :Translator.  Amiga Oberon V2.14

  :History.     V1.0 [phf] 22-Aug-1992 [created] hacked up from Trap.MOD
  :History.     V1.1 [phf] 22-Aug-1992 added Disable/Enable protection
  :History.     V1.1 [phf] 22-Aug-1992 [last edit]

  :Support.     Some support from Martin Berndt. Thanx.
  :Imports.     -
  :Bugs.        none known

  :Address.     Peter Fröhlich, Ebenböckstraße 19, D-8000 München 60
  :Address.     Z-NET:P.FROEHLICH@AMC.ZER

  :Update.      -

  :Remark.      This module helps to make hard-wired and ugly system
  :Remark.      patches more compatible with new processors.
  :Remark.      I don't want to encourage illegal patching, but I
  :Remark.      want it to be as safe and compatible as possible.

  :Usage.       -

*)
(* ==================================================================== *)

(* $CaseChk- $NilChk- $OvflChk- $RangeChk- $ReturnChk- $TypeChk- *)

MODULE VBR;

IMPORT
  e := Exec, SYSTEM;

(* ==================================================================== *)
(* === assembler routines for VBR access ============================== *)
(* ==================================================================== *)

(*
 *  The assembler routines have to run in supervisor mode, otherwise
 *  they will crash the system. Take care!
 *)

PROCEDURE * GETVBR(); (* $EntryExitCode- *)
BEGIN
  SYSTEM.INLINE(04E7AH, 0801H,  (* movec.l VBR,d0 *)
                04E73H);        (* rte            *)
END GETVBR;

PROCEDURE * SETVBR(); (* $EntryExitCode- *)
BEGIN
  SYSTEM.INLINE(04E7BH, 0801H,  (* movec.l d0,VBR *)
                04E73H);        (* rte            *)
END SETVBR;

(* ==================================================================== *)

PROCEDURE GetVBR*(): SYSTEM.ADDRESS;
(*
 * GetVBR - returns value of VBR register. Returns NIL on 68000,
 *          proper value on 68010+.
 *)
BEGIN
  IF ( e.m68010 IN e.exec.attnFlags ) THEN
    e.Disable();
    SYSTEM.SETREG(1,e.Supervisor(GETVBR));
    e.Enable();
    RETURN SYSTEM.REG(0);
  ELSE
    RETURN NIL;
  END;
END GetVBR;

PROCEDURE SetVBR*(vbr: SYSTEM.ADDRESS): BOOLEAN;
(*
 * SetVBR - sets VBR register to supplied value. Returns TRUE
 *          if operation was successful. If you supply an
 *          illegal address it probably won't return anyway.
 *)
BEGIN
  IF ( e.m68010 IN e.exec.attnFlags ) THEN
    SYSTEM.SETREG(0,vbr);
    e.Disable();
    SYSTEM.SETREG(1,e.Supervisor(SETVBR));
    e.Enable();
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END;
END SetVBR;

(* ==================================================================== *)
END VBR.
(* ==================================================================== *)
