home *** CD-ROM | disk | FTP | other *** search
- (* ┌───────────────────────────────────────────────────────────────────────┐
- │ PROGMAP (3.0) - Belegungsliste des PC-Hauptspeichers │
- │ │
- │ Copyright (c) 1987,1988,1989 Karsten Gieselmann & DMV Software │
- └───────────────────────────────────────────────────────────────────────┘ *)
-
- {$IFDEF Ver40} (* Compilerschalter für Turbo Pascal 4.0 *)
- {$R-,S-,I-,F-,V-,B-,N-}
- {$ENDIF}
-
- {$IFDEF Ver50} (* Compilerschalter für Turbo Pascal 5.0 *)
- {$R-,S-,I-,F-,V-,B-,N-,A-,E-,O-}
- {$ENDIF}
-
-
- Unit ProgMap;
-
- Interface uses Dos;
-
- Type ProgName = String[8]; (* "reiner" Programmname (o. Pfad u. Ext.) *)
-
- EntryPtr = ^ProgEntry; (* Eintrag für ein Programm *)
- ProgEntry = Record
- Segment : Word; (* Lade-Segment *)
- Name : ProgName; (* Name des Programms *)
- Segs : Byte; (* Anzahl der Segmente *)
- Paragraphs : Word; (* belegter Speicher *)
- Prev, (* Zeiger auf letzten Eintrag *)
- Next : EntryPtr; (* Zeiger auf nächsten Eintrag *)
- End;
-
- Var UnUsed : Word; (* Größe der nicht belegten Blöcke in Paragraphen *)
-
-
- Procedure MakeMemoryMap(Var FirstProgPtr : EntryPtr);
-
- (* Diese Routine erstellt eine nach Segmenten aufsteigend geordnete Liste
- aller im Hauptspeicher befindlichen residenten Programme. Der durch un-
- benutzte Blöcke belegte Speicher wird in der globalen Variablen UnUsed
- mitgezählt (Angabe in Paragraphen). Der Zugriff auf die von MakeMemory-
- Map erstellte Liste erfolgt Über den VAR-Parameter FirstProgPtr, dieser
- enthält einen Zeiger auf den ersten Listeneintrag. *)
-
-
-
- Implementation
-
-
- Procedure MakeMemoryMap(Var FirstProgPtr : EntryPtr);
-
- Type MCB_Ptr = ^MCB_Type;
- MCB_Type = Record (* Aufbau eines Memory Control Blocks *)
- ID : Char;
- PSPSeg,
- Diff : Word;
- End;
-
- Var MCB : MCB_Type;
- CurrentMCB : MCB_Ptr;
- FirstProg, (* Listenkopf *)
- ProgPtr : EntryPtr; (* Arbeitszeiger *)
-
-
- Function First_MCB : MCB_Ptr;
-
- (* liefert einen Zeiger auf den ersten Memory Control Block *)
-
- Var Regs : Registers;
-
- Begin
- With Regs do
- Begin
- AH := $52; (* undokumentierte Funktion 52h *)
- MsDos(Regs);
- First_MCB := Ptr(MemW[ES:BX-2], 0);
- End;
- End;
-
-
- Function NewEntry(PSPSeg : Word; Var ProgPtr : EntryPtr) : Boolean;
-
- (* durchsucht die nach Segmenten aufsteigend sortierte Programm-Liste
- und liefert die Einfüge-Position; befindet sich bereits ein Eintrag
- in der Liste, bei welchem das Segment mit "PSPSeg" übereinstimmt, so
- wird ein Zeiger auf diesen Eintrag übergeben. Handelt es sich um ein
- neu in die Liste einzufügendes Element, wird TRUE zurückgegeben. *)
-
- Begin
- ProgPtr := FirstProg;
- While (ProgPtr^.Next <> Nil) and (ProgPtr^.Segment < PSPSeg) do
- ProgPtr := ProgPtr^.Next;
- If ProgPtr <> FirstProg then
- If PSPSeg < ProgPtr^.Segment then
- ProgPtr := ProgPtr^.Prev;
- NewEntry := (ProgPtr^.Segment <> PSPSeg);
- End;
-
-
- Procedure InsertNewProg(Var ProgPtr : EntryPtr);
-
- (* erzeugt ein neues Listenelement und fügt es hinter "ProgPtr" ein *)
-
- Var NewProg : EntryPtr;
-
- Begin
- New(NewProg);
- NewProg^.Next := ProgPtr^.Next;
- NewProg^.Prev := ProgPtr;
- ProgPtr^.Next := NewProg;
- If NewProg^.Next <> Nil then
- NewProg^.Next^.Prev := NewProg;
- ProgPtr := NewProg;
- End;
-
-
- Procedure CheckEnvironment(Segment : Word; Var Name : ProgName);
-
- (* nimmt an, daß es sich bei dem bei Segment:0000 beginnenden Speicher-
- bereich um ein Environment handelt und versucht den Namen des zuge-
- hörigen Programms auszulesen (eingetragen erst ab DOS-Version 3.0!). *)
-
- Const Dot = $2E; {.}
- Colon = $3A; {:}
- BackSlash = $5C; {\}
-
- Var a, b, k : Word; (* Indizes zum Auslesen des Environments *)
-
- Begin
- b := 0;
- While MemW[Segment:b] <> $0000 do Inc(b); (* bis Ende der Variablen *)
- If (MemW[Segment:b+2] = $0001) and (Mem[Segment:b+5] = Colon) then
- Begin
- Inc(b, 7);
- While Mem[Segment:b] <> $00 do Inc(b); (* Ende des Environments *)
- While Mem[Segment:b] <> Dot do Dec(b); (* Anfang des Suffix *)
- Dec(b); a:= b;
- While Mem[Segment:a] <> BackSlash do Dec(a); (* Anfang des Namens *)
- Name[0] := Chr(b-a);
- For k:=1 to Ord(Name[0]) do
- Name[k] := Chr(Mem[Segment:a+k]); (* Namen kopieren *)
- End;
- End;
-
-
- Begin
- New(FirstProg); (* Programm-Liste anlegen *)
- With FirstProg^ do
- Begin
- Segment := 0;
- Next := Nil;
- Prev := Nil;
- End;
- UnUsed := 0;
- CurrentMCB := First_MCB; (* Zeiger auf ersten MCB holen *)
- Repeat
- MCB := CurrentMCB^;
- With MCB do
- If PSPSeg > $0070 then (* belegt und nicht vom DOS benutzt? *)
- Begin
- If NewEntry(PSPSeg, ProgPtr) then
- Begin
- InsertNewProg(ProgPtr); (* neuen Eintrag erzeugen *)
- With ProgPtr^ do
- Begin
- Segment := PSPSeg;
- Segs := 0;
- Paragraphs := 0;
- If ProgPtr = FirstProg^.Next then (* Eintrag ist DOS! *)
- Name := 'DOS'
- else
- Name := '???';
- End;
- End;
- With ProgPtr^ do
- Begin
- Inc(Segs);
- Inc(Paragraphs, MCB.Diff);
- If Name = '???' then
- CheckEnvironment(Succ(Seg(CurrentMCB^)), Name);
- End;
- End
- else
- If PSPSeg = $0000 then (* unbenutzer Speicherblock *)
- Inc(UnUsed, Diff);
- CurrentMCB := Ptr(Seg(CurrentMCB^)+MCB.Diff+1, 0); (* nächster MCB *)
- until MCB.ID = 'Z';
- FirstProgPtr := FirstProg^.Next;
- End;
-
-
- End.