home *** CD-ROM | disk | FTP | other *** search
- (*--------------------------------------------------------*)
- (* BIGARRAY.PAS *)
- (* Verwaltung großer Arrays im Extended/Expanded Memory *)
- (* Turbo Pascal Versionen 4.0 und 5.x *)
- (* Copyright (c) 1989 Karsten Gieselmann & TOOLBOX *)
- (*--------------------------------------------------------*)
-
- {$R+,S+} (* Keine Bereichs- oder Stacküberlauf-Prüfung *)
-
- UNIT BigArray;
-
- {$DEFINE UseEMS} (* soll EMS als Speicher benutzt werden? *)
-
- INTERFACE
-
- USES
- {$IFDEF UseEMS} EMS {$ELSE} XMS {$ENDIF};
-
- TYPE VArray = RECORD (* Virtueller Feldtyp *)
- Handle : WORD;
- Rows, Cols, Size : WORD;
- END;
-
- FUNCTION MakeArray(VAR A : VArray; Rows, Cols,
- ElementSize : WORD) : BOOLEAN;
- PROCEDURE DisposeArray(VAR A : VArray);
- PROCEDURE PutElement(VAR A : VArray; Row, Col : WORD;
- VAR Value);
- PROCEDURE GetElement(VAR A : VArray; Row, Col : WORD;
- VAR Value);
-
- (* ------------------------------------------------------ *)
-
- IMPLEMENTATION
-
- VAR
- BlockSize : WORD; (* Größe eines Speicherblocks/seite *)
-
- FUNCTION MakeArray(VAR A : VArray; Rows, Cols,
- ElementSize : WORD) : BOOLEAN;
- (* legt ein Array mit "Rows" Zeilen und "Cols" Spalten
- im erweiterten Speicher an; die Größe der Elemente
- muß gerade sein! Die Funktion liefert den Wert FALSE,
- falls nicht genügend Speicher zur Verfügung steht. *)
- VAR
- ArraySize : LONGINT;
- BEGIN
- MakeArray := FALSE;
- IF Odd(ElementSize) THEN EXIT; (* Größe muß gerade sein *)
- A.Rows := Rows;
- A.Cols := Cols;
- A.Size := ElementSize;
- ArraySize := LONGINT(A.Size) * Rows * Cols;
- ArraySize := ArraySize DIV BlockSize;
- IF ArraySize MOD BlockSize <> 0 THEN BEGIN
- Inc(ArraySize);
- END;
- A.Handle := AllocateMemory(WORD(ArraySize));
- MakeArray := (Result = Ok);
- END;
-
- PROCEDURE DisposeArray(VAR A : VArray);
- (* gibt den von einem Array belegten erweiterten Spei-
- cher wieder frei. *)
- BEGIN
- DeallocateMemory(A.Handle);
- END;
-
- PROCEDURE MoveElement(VAR A : VArray; Row, Col : WORD;
- VAR Value; GetValue : BOOLEAN);
- (* zentrale Routine zum Transfer zwischen konventionel-
- lem und erweitertem Speicher. *)
- VAR
- Count : WORD;
- Offset : LONGINT;
- Cell, Matrix : Descriptor;
- BEGIN
- Cell.RAM := TRUE; (* Deskriptoren besetzen *)
- Cell.Address := @Value;
- Matrix.RAM := FALSE;
- Matrix.Handle := A.Handle;
- Offset := LONGINT(A.Size) * ((Row-1)*A.Cols+Col-1);
- {$IFDEF UseEMS}
- Matrix.LogicalPage := Offset DIV BlockSize;
- Matrix.Offset := Offset MOD BlockSize;
- Count := A.Size; (* Anzahl Bytes *)
- {$ELSE}
- Matrix.Offset := Offset;
- Count := A.Size DIV 2; (* Anzahl Worte *)
- {$ENDIF};
- IF GetValue THEN BEGIN
- MoveMemory(Matrix, Cell, Count);
- END ELSE BEGIN
- MoveMemory(Cell, Matrix, Count);
- END;
- END;
-
- PROCEDURE PutElement(VAR A : VArray; Row, Col : WORD;
- VAR Value);
- (* besetzt das Element A[Row,Col] mit dem Wert "Value". *)
- BEGIN
- MoveElement(A, Row, Col, Value, FALSE);
- END;
-
- PROCEDURE GetElement(VAR A : VArray; Row, Col : WORD;
- VAR Value);
- (* holt den Wert des Elements A[Row,Col] nach "Value". *)
- BEGIN
- MoveElement(A, Row, Col, Value, TRUE);
- END;
-
- BEGIN
- BlockSize := {$IFDEF UseEMS} 16384 {$ELSE} 1024 {$ENDIF};
- END.
- (* ------------------------------------------------------ *)
- (* Ende von BIGARRAY.PAS *)