home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* OVRXMS.PAS *)
- (* Auslagern von Overlays in den extended Memory *)
- (* (c) 1991 Dirk Schneider & TOOLBOX *)
- (* ------------------------------------------------------ *)
- UNIT OvrXMS;
-
- INTERFACE
-
- CONST
- ovrNoXMSDriver = -7; { XMS-Treiber nicht installiert }
- ovrNoXMSMemory = -8; { nicht genügend Platz im EM }
-
- PROCEDURE OvrInitXMS;
-
- IMPLEMENTATION
-
- USES
- Overlay, XMS;
-
- TYPE
- OvrCtrl = RECORD { Typ eines Overlay-Steuersegments }
- int_3f : INTEGER; { Befehl Int 3F }
- Unterbr : INTEGER; { Ret-Offset für Unterbrechung }
- CodePtr : LONGINT; { Position in der OVR-Datei }
- LENGTH : INTEGER; { Länge des Codes }
- ReTablen : INTEGER; { Länge der Relokationtabelle }
- jmpcnt : INTEGER; { Anzahl der Sprungvektoren }
- nextCode : WORD; { Liste Steuerblöcke }
- Ldadr : WORD; { Lade-Segment }
- stackOfs : WORD; { StackOfs für Unterbrechung }
- nextload : WORD; { Liste Steuerblöcke der gel. Unit }
- EMS_Page : INTEGER; { EMS-Seitennummer }
- EMS_Ofs : WORD; { EMS-Offset }
- User1 : WORD; { 6 Bytes sind frei }
- User2 : WORD;
- User3 : WORD;
- Vector : ARRAY [0..1] OF ARRAY [1..4] OF BYTE;
- END; { Vektoren für Init und 1. Routine }
-
- VAR
- CtrlPtr : ^OvrCtrl; { Zeiger auf Steuersegment }
- OldExitProc : POINTER; { Exit-Prozedur sichern }
-
-
- FUNCTION OwnOvrRead(OvrSeg : WORD) : INTEGER; FAR;
- (* ersetzt Turbo Pascal's OvrRead *)
- BEGIN
- CtrlPtr := PTR(OvrSeg, 0);
- WITH CtrlPtr^ DO
- IF (NOT XMM_Move(PTR(Ldadr, 0), 0, NIL, User2,
- ((LENGTH+1) SHR 1) SHL 1)) THEN
- OvrResult := ovrIOError ELSE OvrResult := ovrOK;
- OwnOvrRead := OvrResult; { Fehler zurück }
- END;
-
- PROCEDURE OvrInitXMS;
- (* kopiert Overlay Units in den ext. Memory *)
- VAR
- chain : WORD;
- error, OvrSize : INTEGER;
- BEGIN
- OvrSize := 0;
- chain := OVRCODELIST;
- WHILE chain <> 0 DO BEGIN { Liste der Steuerseg. }
- CtrlPtr := PTR(chain+PREFIXSEG+$10, 0); { relokieren }
- WITH CtrlPtr^ DO BEGIN
- User1 := (LENGTH+1023) SHR 10; { Größe in kByte }
- INC(OvrSize, User1); { Gesamtgröße merken }
- chain := nextCode;
- END;
- END;
- IF (NOT XMM_avail) THEN BEGIN { XMS-Treiber inst. ?}
- OvrResult := ovrNoXMSDriver;
- Exit;
- END ELSE IF (XMM_Memavail < OvrSize) THEN BEGIN
- OvrResult := ovrNoXMSMemory;
- Exit;
- END; { reicht RAM ? }
- chain := OVRCODELIST;
- WHILE chain <> 0 DO BEGIN
- INC(chain, PREFIXSEG+$10); { relokieren ... }
- CtrlPtr := PTR(chain, 0);
- WITH CtrlPtr^ DO BEGIN
- Ldadr := OVRHEAPORG;
- User2 := XMM_Alloc(User1); { Block im EM }
- IF (User2 = 0) THEN BEGIN
- OvrResult := ovrNoXMSMemory;
- Exit;
- END;
- error := OvrReadBuf(chain); { Ovr-Unit lesen }
- IF error <> 0 THEN BEGIN
- OvrResult := ovrIOError;
- Exit;
- END;
- IF (NOT XMM_Move(NIL, User2, PTR(Ldadr, 0), 0,
- ((LENGTH+1) SHR 1) SHL 1)) THEN BEGIN
- OvrResult := ovrIOError;
- Exit;
- END;
- Ldadr := 0; { Ladeadresse löschen }
- chain := nextCode; { nächstes Steuersegment }
- END;
- END;
- OvrReadBuf := OwnOvrRead;
- { neue OvrRead installieren }
- END;
-
- PROCEDURE OvrExit; FAR;
- (* gibt allokierte Blöcke im ext. Memory frei *)
- VAR
- chain : WORD;
- BEGIN
- chain := OVRCODELIST;
- WHILE chain <> 0 DO BEGIN
- INC(chain, PREFIXSEG+$10);
- CtrlPtr := PTR(chain, 0);
- IF NOT XMM_Free(CtrlPtr^.User2) THEN BEGIN
- OvrResult := ovrIOError;
- Exit;
- END;
- chain := CtrlPtr^.nextCode;
- END;
- EXITPROC := OldExitProc; { alte Exit-Proc laden }
- END;
-
- BEGIN
- OldExitProc := EXITPROC;
- EXITPROC := @OvrExit;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von OVRXMS.PAS *)
-