home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 11 / release.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1989-04-17  |  5.8 KB  |  179 lines

  1. (* ┌───────────────────────────────────────────────────────────────────────┐
  2.    │     RELEASE (3.0)  -  Freigeben eines MARKierten Speicherbereichs     │
  3.    │                                                                       │
  4.    │    Copyright (c) 1987,1988,1989  Karsten Gieselmann & DMV Software    │
  5.    └───────────────────────────────────────────────────────────────────────┘ *)
  6.  
  7. {$IFDEF Ver40}                      (* Compilerschalter für Turbo Pascal 4.0 *)
  8.   {$R-,S-,I-,F-,V-,B-,N-}
  9. {$ENDIF}
  10.  
  11. {$IFDEF Ver50}                      (* Compilerschalter für Turbo Pascal 5.0 *)
  12.   {$R-,S-,I-,F-,V-,B-,N-,A-,E-,O-}
  13. {$ENDIF}
  14.  
  15. {$M 2048, 1024, 655360}                             (* Speicherkonfiguration *)
  16.  
  17.  
  18. Program Release;
  19.  
  20. Uses  Dos, ProgMap;
  21.  
  22. Const OK         = 0;                        (* Rückgabe-Codes für MarkFound *)
  23.       NotFound   = 1;
  24.       ShellError = 2;
  25.  
  26. Var   Seg        : Word;                 (* Segment des letzten MARK-Aufrufs *)
  27.       FirstProg,
  28.       LastProg   : EntryPtr;
  29.  
  30.  
  31. Function MarkFound(Var Segment : Word) : Byte;
  32.  
  33.   (* sucht in der Programm-Liste den letzten MARK-Eintrag;  wird dieser ge-
  34.      funden, so enthält "Segment" das Segment dieses Eintrags. Entsprechend
  35.      dem Erfolg der Operation wird eine Kennzahl (siehe oben) zurückgegeben. *)
  36.  
  37.    Var ProgPtr : EntryPtr;
  38.  
  39.  
  40.    Function MarkFound_ : Boolean;
  41.  
  42.       Type  Search   = Array[0..22] of Char;
  43.  
  44.       Const MarkName = 'MARK';                    (* Name des MARK-Programms *)
  45.  
  46.             MarkCode : Search = (#$FA,#$0E,#$07,#$33,#$C0,#$8E,#$D8,#$89,#$C6,
  47.                                  #$BF,#$17,#$01,#$B9,#$00,#$02,#$F3,#$A5,#$FB,
  48.                                  #$BA,#$17,#$05,#$CD,#$27);
  49.  
  50.       Function DosVersion : Word;
  51.          Inline($B4/$30/$CD/$21);
  52.  
  53.       Begin
  54.       With ProgPtr^ do
  55.          If Lo(DosVersion) >= 3 then
  56.             MarkFound_ := (Name = MarkName)
  57.          else
  58.             MarkFound_ := (Search(Ptr(Segment,$100)^) = Search(MarkCode));
  59.       End;
  60.  
  61.  
  62.    Begin
  63.    MarkFound := NotFound;
  64.    ProgPtr := LastProg;
  65.    While not MarkFound_ and (ProgPtr <> FirstProg) do
  66.       With ProgPtr^ do
  67.          If Name = 'COMMAND' then
  68.             Begin
  69.             MarkFound := ShellError;
  70.             Exit;
  71.             End
  72.          else
  73.             ProgPtr := Prev;
  74.    If ProgPtr <> FirstProg then
  75.       Begin
  76.       Segment := ProgPtr^.Segment;
  77.       MarkFound := OK;
  78.       End;
  79.    End;
  80.  
  81.  
  82. Procedure RestoreIntVecTable(Seg : Word);
  83.  
  84.   (* kopiert die von MARK gesicherte Interrupt-Vektor-Tabelle wieder an ih-
  85.      ren ursprünglichen Platz am Speicheranfang bei Adresse $0000:$0000      *)
  86.  
  87.    Begin
  88.    Inline ($FA/            (*  CLI                ;Interrupts verbieten      *)
  89.            $06/            (*  PUSH    ES         ;Extrasegment sichern      *)
  90.            $1E/            (*  PUSH    DS         ;Datensegment sichern      *)
  91.            $8B/$86/Seg/    (*  MOV     AX,Segm    ;MARK-Segment holen...     *)
  92.            $8E/$D8/        (*  MOV     DS,AX      ;...und nach DS laden      *)
  93.            $BE/$17/$01/    (*  MOV     SI,0117    ;Beginn der IntVec-Tabelle *)
  94.            $31/$C0/        (*  XOR     AX,AX      ;AX löschen, ...           *)
  95.            $8E/$C0/        (*  MOV     ES,AX      ;...als Segment nach ES... *)
  96.            $89/$C7/        (*  MOV     DI,AX      ;...und als Offset nach DI *)
  97.            $B9/$00/$02/    (*  MOV     CX,0200    ;Länge der IntVec-Tabelle  *)
  98.            $F3/            (*  REPZ               ;Kopieren bis Tabellenende *)
  99.            $A5/            (*  MOVSW              ;                          *)
  100.            $1F/            (*  POP     DS         ;Datensegment wiederholen  *)
  101.            $07/            (*  POP     ES         ;Extrasegment wiederholen  *)
  102.            $FB)            (*  STI                ;Interrupts zulassen       *)
  103.    End;
  104.  
  105.  
  106. Procedure GetPtr(Var LastProg : EntryPtr);
  107.  
  108.   (* liefert einen Zeiger auf den letzten Eintrag der Programm-Liste *)
  109.  
  110.    Var ProgPtr : EntryPtr;
  111.  
  112.    Begin
  113.    ProgPtr := FirstProg;
  114.    While ProgPtr^.Next^.Next <> Nil do
  115.       ProgPtr := ProgPtr^.Next;
  116.    LastProg := ProgPtr;
  117.    End;
  118.  
  119.  
  120. Procedure ReleaseMemory(ProgPtr : EntryPtr);
  121.  
  122.   (* gibt den durch "ProgPtr" bezeichneten Speicherbereich wieder frei *)
  123.  
  124.  
  125.    Procedure ReleaseBlock(Segment : Word);
  126.  
  127.      (* gibt das vom DOS allokierte Segment "Segment" wieder frei *)
  128.  
  129.       Var Regs : Registers;
  130.  
  131.       Begin
  132.       With Regs do
  133.          Begin
  134.          ES := Segment;
  135.          AH := $49;                  (* DOS-Funktion "Free Allocated Memory" *)
  136.          MsDos(Regs);
  137.          If Odd(Flags) then
  138.             WriteLn('Error releasing ', ProgPtr^.Name);
  139.          End
  140.       End;
  141.  
  142.  
  143.    Begin
  144.    With ProgPtr^ do
  145.       Begin
  146.       If Segs = 2 then                              (* Environment freigeben *)
  147.          ReleaseBlock(MemW[Segment:$2C]);
  148.       ReleaseBlock(Segment);
  149.       End;
  150.    End;
  151.  
  152.  
  153. Begin
  154. MakeMemoryMap(FirstProg);               (* Zeiger auf erstes  Programm holen *)
  155. GetPtr(LastProg);                       (* Zeiger auf letztes Programm holen *)
  156. WriteLn;
  157. Case MarkFound(Seg) of
  158.  
  159.    OK:
  160.       Begin
  161.       RestoreIntVecTable(Seg);  (* Interrupt-Vektoren wieder auf alten Stand *)
  162.       Repeat
  163.          ReleaseMemory(LastProg);                      (* Speicher freigeben *)
  164.          With LastProg^ do
  165.             If Segment <> Seg then              (* MARK wird nicht angezeigt *)
  166.                WriteLn(Name, ' released....');
  167.          LastProg := LastProg^.Prev;                    (* nächstes Programm *)
  168.       until LastProg^.Segment < Seg;         (* bis MARK-Segment freigegeben *)
  169.       End;
  170.  
  171.    NotFound:
  172.       WriteLn('MARK not found!');
  173.  
  174.    ShellError:
  175.       WriteLn('Cannot release across DOS shells!');
  176.  
  177.    End;
  178. End.
  179.