(*#######################################################################
                              M A G I C A R E A
  #######################################################################
  V1.00         21.10.90  Peter Hellinger
  V0.01         09.09.90  Peter Hellinger
  #######################################################################*)

IMPLEMENTATION MODULE mtArea;

(*------------------------------*)
(*       COMPILERSWITCHES       *)
(*------------------------------*)
(*  TDI-Version:   DEAKTIVIERT  *)
(*------------------------------*)
(* V-  Overflow-Checks          *)
(* R-  Range-Checks             *)
(* S-  Stack-Check              *)
(* N-  NIL-Checks               *)
(* T-  TDI-Compiler vor 3.01    *)
(* Q+  Branch statt Jumps       *)
(*                              *)
(*------------------------------*)
(*  MM2-Version:     AKTIVIERT  *)
(*------------------------------*)
(*$R-   Range-Checks            *)
(*$S-   Stack-Check             *)
(*                              *)
(*------------------------------*)


FROM SYSTEM     IMPORT  ADDRESS, ADR, WORD, LONGWORD, BYTE;
FROM Storage    IMPORT  ALLOCATE, DEALLOCATE;
FROM MagicSys   IMPORT  Nil, Null, Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7,
                        Bit8, Bit9, Bit10, Bit11, Bit12, Bit13, Bit14, Bit15,
                        LOC, Byte, ByteSet, sWORD, sINTEGER, sCARDINAL, sBITSET,
                        lWORD, lINTEGER, lCARDINAL, lBITSET,
                        CastToChar, CastToByte, CastToByteset, CastToInt,
                        CastToCard, CastToBitset, CastToWord, CastToLInt,
                        CastToLCard, CastToLBitset, CastToLWord, CastToAddr;
FROM MagicVDI   IMPORT  VDIIntIn, VDIIntOut, VDIPtsIn, VDIPtsOut, VDIControl,
                        VDICall, tWorkIn, tWorkOut, MFDB;
FROM mtAppl     IMPORT  VDIHandle, Bitplanes, MouseOn, MouseOff;
IMPORT  MagicAES, MagicVDI;

TYPE    AREA =          POINTER TO Area;
        Area =          RECORD
                         x:     sINTEGER;
                         y:     sINTEGER;
                         w:     sINTEGER;
                         h:     sINTEGER;
                         init:  BOOLEAN;
                         size:  lCARDINAL;
                         mfdb:  MFDB;
                        END;

VAR     control7:       POINTER TO ADDRESS; (* it's tricky... *)
        control9:       POINTER TO ADDRESS;
        r:              POINTER TO tRect;

VAR     ScreenMFDB:     MFDB;   (* MFDB fr Bildschirm    *)
        Screen:         tRect;  (* Ausmae des gesamten Schirms *)

PROCEDURE NewAREA (VAR a: AREA): BOOLEAN;
BEGIN
 ALLOCATE (a,  TSIZE (Area));  
 IF a = NIL THEN  RETURN FALSE;  END;
 a^.x:= -1;
 a^.y:= -1;
 a^.w:= -1;
 a^.h:= -1;
 a^.init:= FALSE;
 a^.size:= 0FFFFFFFFH;
 a^.mfdb.fdAddr:= NIL;
 RETURN TRUE;
END NewAREA;

PROCEDURE DisposeAREA (VAR a: AREA);
BEGIN
 IF a = NIL THEN  RETURN;  END;
 DEALLOCATE (a^.mfdb.fdAddr, 0);  
 DEALLOCATE (a, 0);  
 a:= NIL;
END DisposeAREA;

PROCEDURE FreeArea (a: AREA);
BEGIN
 IF a = NIL THEN  RETURN;  END;
 DEALLOCATE (a^.mfdb.fdAddr, 0);  
 a^.x:= -1;  a^.y:= -1;  a^.w:= -1;  a^.h:= -1;
 a^.init:= FALSE;
 a^.size:= 0FFFFFFFFH;
 a^.mfdb.fdAddr:= NIL;
END FreeArea;

PROCEDURE SaveArea (a: AREA; rect: ARRAY OF LOC): BOOLEAN;
VAR b,c,d,e: sINTEGER;
BEGIN
 IF a = NIL THEN  RETURN FALSE;  END;
 r:= ADR (rect);
 b:= r^.x;  c:= r^.y;  d:= r^.w;  e:= r^.h;
 WITH a^ DO
  IF init AND ((d > w) OR (e > h)) THEN
   DEALLOCATE (mfdb.fdAddr, 0);   init:= FALSE;
  END;
  IF NOT init THEN
   mfdb.fdWdwidth:= (d + 15) DIV 16;
   mfdb.fdW:= mfdb.fdWdwidth * 16;
   mfdb.fdH:= e + 1;
   mfdb.fdStand:= 0;
   mfdb.fdNplanes:= Bitplanes;
   size:= LONG (mfdb.fdWdwidth) * LONG (mfdb.fdH) * LONG (Bitplanes) * LONG (2);
   ALLOCATE (mfdb.fdAddr,  size);  
   IF mfdb.fdAddr = NIL THEN  RETURN FALSE;  END;
   init:= TRUE;
  END;
  x:= b;  y:= c;  w:= d;  h:= e;
  MouseOff;
  VDIIntIn[0]:= 3;
  VDIPtsIn[0]:= x;
  VDIPtsIn[1]:= y;
  VDIPtsIn[2]:= x + w - 1;
  VDIPtsIn[3]:= y + h - 1;
  VDIPtsIn[4]:= 0;
  VDIPtsIn[5]:= 0;
  VDIPtsIn[6]:= w - 1;
  VDIPtsIn[7]:= h - 1;
  control7^:= ADR (ScreenMFDB);
  control9^:= ADR (mfdb);
  VDICall (109, 4, 1, 0, VDIHandle);
  MouseOn;
 END;
 RETURN TRUE;
END SaveArea;

PROCEDURE RestoreArea (a: AREA);
BEGIN
 IF a = NIL THEN  RETURN;  END;
 WITH a^ DO
  IF init THEN
   MouseOff;
   VDIIntIn[0]:= 3;
   VDIPtsIn[0]:= 0;
   VDIPtsIn[1]:= 0;
   VDIPtsIn[2]:= w - 1;
   VDIPtsIn[3]:= h - 1;
   VDIPtsIn[4]:= x;
   VDIPtsIn[5]:= y;
   VDIPtsIn[6]:= x + VDIPtsIn[2];
   VDIPtsIn[7]:= y + VDIPtsIn[3];
   control7^:= ADR (mfdb);
   control9^:= ADR(ScreenMFDB);
   VDICall (109, 4, 1, 0, VDIHandle);
   MouseOn;
  END;
 END;
END RestoreArea;

PROCEDURE CopyArea (a: AREA; xx, yy: INTEGER);
BEGIN
 IF a = NIL THEN  RETURN;  END;
 WITH a^ DO
  IF init THEN
   MouseOff;
   VDIIntIn[0]:= 3;
   VDIPtsIn[0]:= 0;
   VDIPtsIn[1]:= 0;
   VDIPtsIn[2]:= w - 1;
   VDIPtsIn[3]:= h - 1;
   VDIPtsIn[4]:= xx;
   VDIPtsIn[5]:= yy;
   VDIPtsIn[6]:= xx + VDIPtsIn[2];
   VDIPtsIn[7]:= yy + VDIPtsIn[3];
   control7^:= ADR (mfdb);
   control9^:= ADR(ScreenMFDB);
   VDICall (109, 4, 1, 0, VDIHandle);
   MouseOn;
  END;
 END;
END CopyArea;

PROCEDURE MoveArea (a: AREA; p, dir: INTEGER; VAR xx, yy: INTEGER);
BEGIN
 IF a = NIL THEN  RETURN  END;
 IF a^.init AND (p > 0) THEN
  MagicAES.WindGet (0, MagicAES.WFFULLXYWH, Screen);
  MouseOff;
  VDIIntIn[0]:= 3;
  CASE dir OF
   MOVEUP:    WITH a^ DO
               IF p >= a^.h THEN  p:= a^.h - 1;  END;
               WHILE (y - p) < Screen.y  DO  DEC (p);  END;
               IF p > 0 THEN
                (* Bildschirm teilrestaurieren *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= h - p;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= x;
                VDIPtsIn[5]:= y + h - p;
                VDIPtsIn[6]:= x + w - 1;
                VDIPtsIn[7]:= y + h - 1;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (ScreenMFDB);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Rest intern verschieben *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h - p;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= p;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Bildschirm neuen Teil sichern *)
                VDIPtsIn[0]:= x;
                VDIPtsIn[1]:= y - p;
                VDIPtsIn[2]:= x + w - 1;
                VDIPtsIn[3]:= y - 1;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= p - 1; (* - 1 added by DS *)
                control7^:=   ADR (ScreenMFDB);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                DEC (y, p);
               END;
              END;
              |
   MOVEDOWN:  WITH a^ DO
               IF p >= a^.h THEN  p:= a^.h - 1;  END;
               WHILE (y + h + p) > (Screen.y + Screen.h) DO  DEC (p);  END;
               IF p > 0 THEN
                (* Bildschirm teilrestaurieren *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= p - 1;
                VDIPtsIn[4]:= x;
                VDIPtsIn[5]:= y;
                VDIPtsIn[6]:= x + w - 1;
                VDIPtsIn[7]:= y + p - 1;
                control7^:= ADR (mfdb);
                control9^:= ADR (ScreenMFDB);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Rest intern verschieben *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= p;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h - p;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Bildschirm neuen Teil sichern *)
                VDIPtsIn[0]:= x;
                VDIPtsIn[1]:= y + h;
                VDIPtsIn[2]:= x + w - 1;
                VDIPtsIn[3]:= y + h + p - 1;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= h - p;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (ScreenMFDB);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                INC (y, p);
               END;
              END;
              |
   MOVELEFT:  WITH a^ DO
               IF p >= a^.w THEN  p:= a^.w - 1;  END;
               WHILE (x - p) < 0  DO  DEC(p);  END;
               IF p > 0 THEN
                (* Bildschirm teilrestaurieren *)
                VDIPtsIn[0]:= w - p;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= x + w - p;
                VDIPtsIn[5]:= y;
                VDIPtsIn[6]:= x + w - 1;
                VDIPtsIn[7]:= y + h - 1;
                control7^:=  ADR (mfdb);
                control9^:=  ADR (ScreenMFDB);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Rest intern verschieben *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - p - 1; (* - 1 added by DS *)
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= p;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Bildschirm neuen Teil sichern *)
                VDIPtsIn[0]:= x - p;
                VDIPtsIn[1]:= y;
                VDIPtsIn[2]:= x - 1;
                VDIPtsIn[3]:= y + h - 1;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= p - 1;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (ScreenMFDB);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                DEC (x, p);
               END;
              END;
              |
   MOVERIGHT: WITH a^ DO
               IF p >= a^.w THEN  p:= a^.w - 1;  END;
               WHILE (x + w + p) > (Screen.x + Screen.w) DO  DEC (p);  END;
               IF p > 0 THEN
                (* Bildschirm teilrestaurieren *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= p - 1;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= x;
                VDIPtsIn[5]:= y;
                VDIPtsIn[6]:= x + p - 1;
                VDIPtsIn[7]:= y + h - 1;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (ScreenMFDB);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Rest intern verschieben *)
                VDIPtsIn[0]:= p;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - p - 1; (* - 1 added by DS *)
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Bildschirm neuen Teil sichern *)
                VDIPtsIn[0]:= x + w;
                VDIPtsIn[1]:= y;
                VDIPtsIn[2]:= x + w + p - 1;
                VDIPtsIn[3]:= y + h - 1;
                VDIPtsIn[4]:= w - p;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (ScreenMFDB);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                INC (x, p);
               END;
              END;
              |
   ELSE       ;
  END;
  MouseOn;
  xx:= a^.x;
  yy:= a^.y;
 END;
END MoveArea;

VAR init: sCARDINAL;

PROCEDURE InitMtArea;
BEGIN
 IF init # 30961 THEN
  ScreenMFDB.fdAddr:= Null;
  control7:= ADR (VDIControl[7]);
  control9:= ADR (VDIControl[9]);
  init:= 30961;
 END;
END InitMtArea;

BEGIN
 init:= 0;
 InitMtArea;
END mtArea.

TYPE    tRect =         RECORD
                         x: sINTEGER;
                         y: sINTEGER;
                         w: sINTEGER;
                         h: sINTEGER;
                        END;

TYPE    AREA =          POINTER TO Area;
        Area =          RECORD
                         x:     sINTEGER;
                         y:     sINTEGER;
                         w:     sINTEGER;
                         h:     sINTEGER;
                         init:  BOOLEAN;
                         size:  lCARDINAL;
                         mfdb:  MFDB;
                        END;

VAR     control7:       POINTER TO ADDRESS; (* it's tricky... *)
        control9:       POINTER TO ADDRESS;
        array:          POINTER TO ARRAY [0..50] OF sINTEGER;

VAR     ScreenMFDB:     MFDB;   (* MFDB fr Bildschirm    *)
        Screen:         tRect;  (* Ausmae des gesamten Schirms *)


PROCEDURE NewAREA (VAR a: AREA): BOOLEAN;
BEGIN
 NEW (a);
 IF a = NIL THEN  RETURN FALSE;  END;
 a^.x:= -1;
 a^.y:= -1;
 a^.w:= -1;
 a^.h:= -1;
 a^.init:= FALSE;
 a^.size:= 0FFFFFFFFH;
 a^.mfdb.fdAddr:= NIL;
 RETURN TRUE;
END NewAREA;        


PROCEDURE DisposeAREA (VAR a: AREA);
BEGIN
 IF a = NIL THEN  RETURN;  END;
 DEALLOCATE (a^.mfdb.fdAddr, a^.size);
 DISPOSE (a);  a:= NIL;
END DisposeAREA;


PROCEDURE FreeArea (a: AREA);
BEGIN
 IF a = NIL THEN  RETURN;  END;
 DEALLOCATE (a^.mfdb.fdAddr, a^.size);
 a^.x:= -1;
 a^.y:= -1;
 a^.w:= -1;
 a^.h:= -1;
 a^.init:= FALSE;
 a^.size:= 0FFFFFFFFH;
 a^.mfdb.fdAddr:= NIL;
END FreeArea;


PROCEDURE SaveArea (a: AREA; rect: ARRAY OF LOC): BOOLEAN;
VAR b,c,d,e: sINTEGER;
BEGIN
 IF a = NIL THEN  RETURN FALSE;  END;
 array:= ADR (rect);
 b:= array^[0];
 c:= array^[1];
 d:= array^[2];
 e:= array^[3];
 WITH a^ DO
  IF init AND ((d > w) OR (e > h)) THEN
   DEALLOCATE (mfdb.fdAddr, size);
   init:= FALSE;
  END;
  IF NOT init THEN
   mfdb.fdWdwidth:= (d + 15) DIV 16;
   mfdb.fdW:=       mfdb.fdWdwidth * 16;
   mfdb.fdH:=       e + 1;
   mfdb.fdStand:=   0;
   mfdb.fdNplanes:= Bitplanes;
   size:= LONG (mfdb.fdWdwidth) * LONG (mfdb.fdH) * LONG (Bitplanes) * LONG (2);
   ALLOCATE (mfdb.fdAddr, size);
   IF mfdb.fdAddr = NIL THEN  RETURN FALSE;  END;
   init:= TRUE;
  END;
  x:= b;  y:= c;  w:= d;  h:= e;
  MouseOff;
  VDIIntIn[0]:= 3;
  VDIPtsIn[0]:= x;
  VDIPtsIn[1]:= y;
  VDIPtsIn[2]:= x + w - 1;
  VDIPtsIn[3]:= y + h - 1;
  VDIPtsIn[4]:= 0;
  VDIPtsIn[5]:= 0;
  VDIPtsIn[6]:= w - 1;
  VDIPtsIn[7]:= h - 1;
  control7^:= ADR (ScreenMFDB);
  control9^:= ADR (mfdb);
  VDICall (109, 4, 1, 0, VDIHandle);
  MouseOn; 
 END;
 RETURN TRUE;
END SaveArea;


PROCEDURE RestoreArea (a: AREA);
BEGIN
 IF a = NIL THEN  RETURN;  END;
 WITH a^ DO
  IF init THEN
   MouseOff;
   VDIIntIn[0]:= 3;
   VDIPtsIn[0]:= 0;
   VDIPtsIn[1]:= 0;
   VDIPtsIn[2]:= w - 1;
   VDIPtsIn[3]:= h - 1;
   VDIPtsIn[4]:= x;
   VDIPtsIn[5]:= y;
   VDIPtsIn[6]:= x + VDIPtsIn[2];
   VDIPtsIn[7]:= y + VDIPtsIn[3];
   control7^:= ADR (mfdb);
   control9^:= ADR(ScreenMFDB);
   VDICall (109, 4, 1, 0, VDIHandle);
   MouseOn;
  END;
 END;
END RestoreArea;


PROCEDURE CopyArea (a: AREA; xx, yy: INTEGER);
BEGIN
 IF a = NIL THEN  RETURN;  END;
 WITH a^ DO
  IF init THEN
   MouseOff;
   VDIIntIn[0]:= 3;
   VDIPtsIn[0]:= 0;
   VDIPtsIn[1]:= 0;
   VDIPtsIn[2]:= w - 1;
   VDIPtsIn[3]:= h - 1;
   VDIPtsIn[4]:= xx;
   VDIPtsIn[5]:= yy;
   VDIPtsIn[6]:= xx + VDIPtsIn[2];
   VDIPtsIn[7]:= yy + VDIPtsIn[3];
   control7^:= ADR (mfdb);
   control9^:= ADR(ScreenMFDB);
   VDICall (109, 4, 1, 0, VDIHandle);
   MouseOn;
  END;
 END;
END CopyArea;


PROCEDURE MoveArea (a: AREA; p, dir: INTEGER; VAR xx, yy: INTEGER);
BEGIN
 IF a = NIL THEN  RETURN  END;
 IF a^.init AND (p > 0) THEN
  MagicAES.WindGet (0, MagicAES.WFFULLXYWH, Screen);
  MouseOff;
  VDIIntIn[0]:= 3;
  CASE dir OF
   MOVEUP:    WITH a^ DO
               IF p > a^.h THEN  p:= a^.h;  END;
               WHILE (y - p) < Screen.y  DO  DEC (p);  END;
               IF p > 0 THEN
                (* Bildschirm teilrestaurieren *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= h - p;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= x;
                VDIPtsIn[5]:= y + h - p;
                VDIPtsIn[6]:= x + w - 1;
                VDIPtsIn[7]:= y + h - 1;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (ScreenMFDB);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Rest intern verschieben *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h - p;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= p;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Bildschirm neuen Teil sichern *)
                VDIPtsIn[0]:= x;
                VDIPtsIn[1]:= y - p;
                VDIPtsIn[2]:= x + w - 1;
                VDIPtsIn[3]:= y - 1;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= p;
                control7^:=   ADR (ScreenMFDB);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                DEC (y, p);
               END;
              END;
              |
   MOVEDOWN:  WITH a^ DO  
               IF p > a^.h THEN  p:= a^.h;  END;
               WHILE (y + h + p) > (Screen.y + Screen.h) DO  DEC (p);  END;
               IF p > 0 THEN
                (* Bildschirm teilrestaurieren *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= p - 1;
                VDIPtsIn[4]:= x;
                VDIPtsIn[5]:= y;
                VDIPtsIn[6]:= x + w - 1;
                VDIPtsIn[7]:= y + p - 1;
                control7^:= ADR (mfdb);
                control9^:= ADR (ScreenMFDB);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Rest intern verschieben *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= p;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h - p;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Bildschirm neuen Teil sichern *)
                VDIPtsIn[0]:= x;
                VDIPtsIn[1]:= y + h;
                VDIPtsIn[2]:= x + w - 1;
                VDIPtsIn[3]:= y + h + p - 1;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= h - p;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (ScreenMFDB);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                INC (y, p);
               END;
              END;
              |
   MOVELEFT:  WITH a^ DO
               IF p > a^.w THEN  p:= a^.w;  END;
               WHILE (x - p) < 0  DO  DEC(p);  END;
               IF p > 0 THEN
                (* Bildschirm teilrestaurieren *)
                VDIPtsIn[0]:= w - p;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= x + w - p;
                VDIPtsIn[5]:= y;
                VDIPtsIn[6]:= x + w - 1;
                VDIPtsIn[7]:= y + h - 1;
                control7^:=  ADR (mfdb);
                control9^:=  ADR (ScreenMFDB);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Rest intern verschieben *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - p;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= p;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Bildschirm neuen Teil sichern *)
                VDIPtsIn[0]:= x - p;
                VDIPtsIn[1]:= y;
                VDIPtsIn[2]:= x - 1;
                VDIPtsIn[3]:= y + h - 1;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= p - 1;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (ScreenMFDB);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                DEC (x, p);
               END;
              END;
              |
   MOVERIGHT: WITH a^ DO
               IF p > a^.w THEN  p:= a^.w;  END;
               WHILE (x + w + p) > (Screen.x + Screen.w) DO  DEC (p);  END;
               IF p > 0 THEN
                (* Bildschirm teilrestaurieren *)
                VDIPtsIn[0]:= 0;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= p - 1;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= x;
                VDIPtsIn[5]:= y;
                VDIPtsIn[6]:= x + p - 1;
                VDIPtsIn[7]:= y + h - 1;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (ScreenMFDB);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Rest intern verschieben *)
                VDIPtsIn[0]:= p;
                VDIPtsIn[1]:= 0;
                VDIPtsIn[2]:= w - 1;
                VDIPtsIn[3]:= h - 1;
                VDIPtsIn[4]:= 0;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - p;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (mfdb);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                (* Bildschirm neuen Teil sichern *)
                VDIPtsIn[0]:= x + w;
                VDIPtsIn[1]:= y;
                VDIPtsIn[2]:= x + w + p - 1;
                VDIPtsIn[3]:= y + h - 1;
                VDIPtsIn[4]:= w - p;
                VDIPtsIn[5]:= 0;
                VDIPtsIn[6]:= w - 1;
                VDIPtsIn[7]:= h - 1;
                control7^:=   ADR (ScreenMFDB);
                control9^:=   ADR (mfdb);
                VDICall (109, 4, 1, 0, VDIHandle);
                INC (x, p);
               END;
              END;
              |
   ELSE       ;
  END;
  MouseOn;
  xx:= a^.x;
  yy:= a^.y;
 END;
END MoveArea;


BEGIN
 ScreenMFDB.fdAddr:= 0;
 control7:= ADR (VDIControl[7]);
 control9:= ADR (VDIControl[9]);
END mtArea.
