home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------------------------- *)
- (* MANAGER.PAS *)
- (* Integrierter Resident-Software-Manager *)
- (* *)
- (* (c) 1988 TOOLBOX & Karsten Gieselmann *)
- (* ------------------------------------------------------------------------- *)
-
- {$R-,S-,I-,V-,B-,N-} (* keine Fehlerprüfung, größtmögliche Geschwindigkeit! *)
- {$M 8192,0,655360}
-
- PROGRAM Manager;
-
- USES
- Crt, Dos, Scroll; (* benötigte Units *)
-
- (* ------------------------ Allgemeine Konstanten -------------------------- *)
-
- CONST
- Version = 'RSM v1.0'; (* Programmname und Versionsnummer *)
- MonitorID = 'RSM Monitor v1.0'; (* Erkennung für das MONITOR-Programm *)
- IFC = $65; (* Nummer des Interface-Interrupts *)
-
- (* ------------------------------ Dateinamen ------------------------------- *)
-
- CONST
- PickFileName = 'C:\RSM\PICK.TSR'; (* die Pickliste *)
- BatchFileName = 'C:\RSM\LOAD.BAT'; (* Batchdatei zum Laden *)
- ComSpecName = 'C:\COMMAND.COM'; (* Name des Kommandoprozessors *)
-
- (* --------------------------- Farbdefinitionen ---------------------------- *)
-
- CONST
- FrameAttr : BYTE = $0F; (* Rahmen des Manager-Windows *)
- MenuAttr : BYTE = $5F; (* Menü- und Kopfzeile *)
- ProgAttr : BYTE = $70; (* Programmliste *)
- PickAttr : BYTE = $30; (* Pickliste *)
- SelectAttr : BYTE = $1F; (* Auswahlbalken *)
- ReleaseAttr : BYTE = $4F; (* Löschbalken *)
-
- (* -------------- die Texte der Manager-Menüs und -Infobalken -------------- *)
-
- CONST
- MainMenu =
- 'Blättern: '^X','^Y',PgUp,PgDn,Home,End Löschen: Del Laden: Ins';
- PickMenu1 = 'Wählen: '^X','^Y',PgUp,PgDn,Home,End ';
- PickMenu2 = 'Markieren: +,- Laden: Return Abbruch: Esc';
-
- ReleaseMenu =
- 'Wählen: '^X','^Y',PgUp,PgDn,Home,End Löschen: Return Abbruch: Esc';
- Header =
- ' Segment Programm Bytes Vektoren (Erklärung mit Tab) ';
-
- (* --------------- Deklarationen für Programm- und Pickliste --------------- *)
-
- TYPE
- ScreenBuffer = ARRAY[1..4000] OF BYTE; (* Bildschirmpuffer *)
- WindowType = (Full, List, Pick); (* die drei verwendeten Fenster *)
- VectorTable = ARRAY[0..$FF] OF POINTER;
- StringPtr = ^STRING; (* dynamischer Stringtyp *)
- ProgramData = RECORD
- ProgramName : StringPtr; (* Name des Programms *)
- ProgramSeg, (* Ladesegment des Programms *)
- EnvironSeg : WORD; (* Adresse des Umgebungsbereichs *)
- ProgramSize, (* Programmgröße in Bytes *)
- EnvironSize : LONGINT; (* Umgebungsgröße in Bytes *)
- TotalHooked : BYTE; (* Anzahl benutzte Vektoren *)
- HookedVectors : SET OF BYTE; (* Vektoren-Nummern *)
- SavedVectors : ^VectorTable; (* gesicherte Vektoren *)
- END;
-
- CONST
- PickSize = 100; (* maximale Größe der Pickliste *)
- ListSize = 100; (* maximale Größe der Programmliste *)
-
- VAR
- ProgramList : ARRAY[1..ListSize] OF ^ProgramData; (* Programmliste *)
- InfoList : ARRAY[1..ListSize] OF StringPtr;
- PickList : ARRAY[1..PickSize] OF RECORD (* Pickliste *)
- Name, (* Programmname *)
- Params, (* Kommandozeilenparameter *)
- Comment : StringPtr; (* beliebiger Kommentar *)
- Selected : BOOLEAN; (* Programm laden? *)
- END;
- NextPSP, (* PSP des nächsten zu ladenden Programms *)
- LastPick : WORD; (* Index des letzten Picklisten-Eintrags *)
- LastEntry : INTEGER; (* Index des letzten Programmlisten-Eintrags *)
- ReleaseMode, (* ist der Manager im Löschmodus? *)
- DisplayVectors, (* werden Vektoren oder Kommentare angezeigt? *)
- Quit : BOOLEAN; (* soll das Manager-Programm beendet werden? *)
- BatchFile : Text; (* Hilfsdatei zum Laden von Programmen *)
- SaveX, SaveY : BYTE; (* Cursorposition bei Programmstart *)
- Key, (* Variable zur Tastaturabfrage *)
- VideoSegment : WORD; (* Segmentadresse des Bildschirmspeichers *)
- MainBuffer, (* Puffer zum Sichern von Bildschirmen *)
- TempBuffer : ScreenBuffer;
- PickMenu : STRING;
-
- (* ---------------- Routinen zur Zeichenkettenverarbeitung ----------------- *)
-
- FUNCTION StringOf(Ch : Char; Len : BYTE) : STRING;
- (* liefert eine Zeichenkette der Länge "Len" bestehend aus "Ch" *)
- VAR
- Temp : STRING;
- BEGIN
- FillChar(Temp[1], Len, Ch);
- Temp[0] := Chr(Len);
- StringOf := Temp;
- END;
-
-
- FUNCTION LeftAligned(St : STRING; Width : BYTE) : STRING;
- (* liefert den String "St" linksbündig in "Width" Zeichen breitem Feld *)
- VAR
- Temp : STRING;
- BEGIN
- FillChar(Temp[1], Width, ' ');
- Temp := St;
- Temp[0] := Chr(Width);
- LeftAligned := Temp;
- END;
-
-
- FUNCTION Centered(St : STRING; Width : BYTE) : STRING;
- (* liefert den String "St" zentriert in "Width" Zeichen breitem Feld *)
- VAR
- Temp : STRING;
- BEGIN
- Temp := StringOf(' ', Width);
- Move(St[1], Temp[1+(Width-Length(St)) DIV 2], Length(St));
- Centered := Temp;
- END;
-
-
- FUNCTION NumStr(n : LONGINT; Width : BYTE) : STRING;
- (* liefert die Ganzzahl "n" als Zeichenkette in einem "Width" breiten Feld *)
- VAR
- St : STRING;
- BEGIN
- Str(n:Width, St);
- NumStr := St
- END;
-
-
- FUNCTION Hex(b : BYTE) : STRING;
- (* Konvertierung eines Dezimalbytes nach Hexadezimal *)
- CONST
- HexDigit : ARRAY[0..15] OF Char = '0123456789ABCDEF';
- BEGIN
- Hex := HexDigit[b SHR $04] + HexDigit[b AND $0F]
- END;
-
-
- FUNCTION HexW(w : WORD) : STRING;
- (* Konvertierung eines Dezimalworts nach Hexadezimal *)
- BEGIN
- HexW := Hex(w SHR $08) + Hex(w AND $FF)
- END;
-
-
- FUNCTION JustName(FileName : STRING) : STRING;
- (* liefert den reinen Dateinamen von "FileName" (ohne Pfad und Extension) *)
- VAR
- j, k : BYTE;
- BEGIN
- j := Length(FileName);
- k := j;
- WHILE (FileName[j] <> '\') AND (FileName[j] <> ':') AND (j > 0) DO Dec(j);
- WHILE (FileName[k] <> '.') AND (k > j) DO Dec(k);
- IF j = k THEN
- k := Succ(Length(FileName));
- JustName := Copy(FileName, Succ(j), Pred(k-j));
- END;
-
-
- PROCEDURE DisposeStr(VAR SPtr : StringPtr);
- (* gibt den von "SPtr" belegten dynamischen Speicher wieder frei *)
- BEGIN
- IF SPtr <> NIL THEN BEGIN (* belegt Stringvariable dynamischen Speicher? *)
- FreeMem(SPtr, Succ(Length(SPtr^))); (* ja, dann freigeben *)
- SPtr := NIL;
- END;
- END;
-
-
- PROCEDURE AssignStr(VAR SPtr : StringPtr; St : STRING);
- (* weist der dynamischen STRING-Variablen "SPtr" die Zeichenkette "St" zu *)
- BEGIN
- IF SPtr <> NIL THEN (* falls noch belegt, Speicher erst freigeben *)
- DisposeStr(SPtr);
- GetMem(SPtr, Succ(Length(St))); (* neuen Speicherplatz anfordern... *)
- Move(St, SPtr^, Succ(Length(St))); (* ...und STRING abspeichern *)
- END;
-
- (* ----------------- Routinen zur Bildschirmansteuerung -------------------- *)
-
- TYPE
- FrameChars = (LeftTop,RightTop,LeftBottom,RightBottom,Horizontal,Vertical);
- FrameType = ARRAY[FrameChars] OF Char; (* Rahmen-Zeichensatz *)
-
- CONST
- Simple = '┌┐└┘─│'; (* vordefinierte Rahmentypen *)
- Double = '╔╗╚╝═║';
-
- VAR
- VideoMode : BYTE ABSOLUTE $0040:$0049; (* aktueller Bildschirmmodus *)
-
-
- PROCEDURE SetAttribute(Attr : BYTE);
- (* setzt Vorder- und Hintergrundfarbe gemäß "Attr" *)
- BEGIN
- TextAttr := Attr; (* direkte Manipulation des Turbo-Videoattributs! *)
- END;
-
-
- PROCEDURE CursorOff; (* macht den Cursor unsichtbar *)
- INLINE($B4/$01/$B9/$00/$F0/$CD/$10);
-
-
- PROCEDURE WriteString(Col, Row : BYTE; St : STRING; Attr : BYTE);
- (* Ausgabe der Zeichenkette "St" bei (Col,Row) mit der Farbe "Attr" *)
- VAR
- Save : WORD;
- BEGIN
- GotoXY(Col, Row); (* Cursor positionieren *)
- TextAttr := Attr;
- Save := WindMax; (* obere Fenstergrenzen sichern *)
- WindMax := $FFFF; (* automatisches CR/LF am Zeilenende verhindern *)
- Write(St);
- WindMax := Save; (* Fenstergrenze wieder herstellen *)
- END;
-
-
- PROCEDURE DrawFrame(Left, Top, Right, Bottom : BYTE; (* Eckpunkte *)
- Title : STRING; (* Überschrift *)
- Offset : BYTE; (* Titel-Position *)
- Style : FrameType); (* Zeichensatz *)
- (* zeichnet einen Rahmen mit den Eckpunkten (Left,Top) und (Right,Bottom). *)
- (* Die Überschrift "Title" wird mit einem Abstand von "Offset" Positionen *)
- (* zum linken Rand des Rahmens in die obere Querleiste eingefügt; bei ei- *)
- (* nem "Offset" von Null wird die Überschrift zentriert. *)
- VAR
- k, Len : BYTE;
- Bar : STRING;
- BEGIN
- Len := Succ(Right-Left);
- Bar := StringOf(Style[Horizontal], Len-2);
- WriteString(Left, Top, Style[LeftTop]+Bar+Style[RightTop], TextAttr);
- WriteString(Left, Bottom, Style[LeftBottom]+Bar+Style[RightBottom],TextAttr);
- FOR k:=Succ(Top) TO Pred(Bottom) DO BEGIN
- GotoXY(Left , k); Write(Style[Vertical]);
- GotoXY(Right, k); Write(Style[Vertical]);
- END;
- IF Length(Title) <= Pred(Len) THEN BEGIN
- IF Offset = 0 THEN (* Titel zentrieren? *)
- Offset := (Succ(Len)-Length(Title)) SHR 1;
- WriteString(Left+Offset, Top, Title, TextAttr)
- END
- END;
-
-
- PROCEDURE SaveScreenTo(VAR Buffer : ScreenBuffer);
- (* sichert den Bildschirminhalt nach "Buffer" *)
- BEGIN
- Move(Mem[VideoSegment:0], Buffer, SizeOf(Buffer));
- END;
-
-
- PROCEDURE RestoreScreenFrom(VAR Buffer : ScreenBuffer);
- (* restauriert den Bildschirminhalt mit "Buffer" *)
- BEGIN
- Move(Buffer, Mem[VideoSegment:0], SizeOf(Buffer));
- END;
-
- (* -------------------- Routinen zur Tastaturabfrage ----------------------- *)
-
- CONST (* Tastencodes *)
- Home = $4700; End_ = $4F00; Tab = $0F09;
- Ins = $5200; Del = $5300; Esc = $011B;
- Return = $1C0D; Down = $5000; Left = $4B00;
- Right = $4D00;
-
-
- FUNCTION GetKey : WORD;
- (* wartet auf Tastendruck und liefert den Scan-Code der Taste *)
- INLINE ($31/$C0/$CD/$16);
-
- (* ----------------- Ausgaberoutinen für Scrollaktionen -------------------- *)
-
- {$F+}
-
- PROCEDURE WriteNormalTSR(Col, Row : BYTE; Index : LONGINT);
- (* Ausgabe eines normalen Eintrags der Programmliste *)
- BEGIN
- IF ReleaseMode AND (Index >= SelectIndex) THEN
- WriteString(Col, Row, LeftAligned(InfoList[Index]^, 78), ReleaseAttr)
- ELSE
- WriteString(Col, Row, LeftAligned(InfoList[Index]^, 78), ProgAttr);
- END;
-
-
- PROCEDURE WriteSelectedTSR(Col, Row : BYTE; Index : LONGINT);
- (* Ausgabe des selektierten Eintrags der Programmliste *)
- BEGIN
- IF ReleaseMode THEN
- WriteString(Col, Row, LeftAligned(InfoList[Index]^, 78), ReleaseAttr)
- ELSE
- WriteString(Col, Row, LeftAligned(InfoList[Index]^, 78), SelectAttr)
- END;
-
-
- PROCEDURE WriteNormalPick(Col, Row : BYTE; Index : LONGINT);
- (* Ausgabe eines normalen Eintrags der Pickliste *)
- VAR
- Entry : STRING;
- BEGIN
- WITH PickList[Index] DO BEGIN
- Entry := LeftAligned(' '+JustName(Name^), 11);
- IF Selected THEN
- Entry[2] := #4; (* Marker setzen *)
- WriteString(Col, Row, Entry, PickAttr);
- END;
- END;
-
-
- PROCEDURE WriteSelectedPick(Col, Row : BYTE; Index : LONGINT);
- (* Ausgabe des selektierten Eintrags der Pickliste *)
- VAR
- Entry : STRING;
- BEGIN
- WITH PickList[Index] DO BEGIN
- Entry := LeftAligned(' '+JustName(Name^), 11);
- IF Selected THEN
- Entry[2] := #4; (* Marker setzen *)
- WriteString(Col, Row, Entry, SelectAttr);
- END;
- END;
-
- {$F-}
-
- (* --------------------- Diverse High-Level-Utilities ---------------------- *)
-
- PROCEDURE SwitchWindow(NewWindow : WindowType);
- (* leitet Bildschirmausgabe auf das Fenster "NewWindow" um *)
- VAR
- ColSize : BYTE;
- BEGIN
- CASE NewWindow OF
- Full : Window(1, 1, 80, 25);
- List : Window(2, 4, 79, 22);
- Pick : BEGIN
- SwitchWindow(Full);
- SetAttribute(PickAttr);
- ColSize := LastPick + 4;
- IF ColSize > 21 THEN
- ColSize := 21;
- DrawFrame(66, 4, 78, Succ(ColSize), ' Laden ', 0, Simple);
- Window(67, 5, 77, ColSize);
- END;
- END;
- END;
-
-
- PROCEDURE Inform(Message : STRING);
- (* gibt eine Meldung in der Menü- und Infozeile aus *)
- VAR
- SaveMin, SaveMax : WORD;
- BEGIN
- SaveMin := WindMin; (* aktuelle Fenstergrenzen sichern *)
- SaveMax := WindMax;
- SwitchWindow(Full); (* ganzer Bildschirm *)
- WriteString(2, 24, Centered(Message, 78), MenuAttr);
- WindMin := SaveMin; (* Fenster restaurieren *)
- WindMax := SaveMax;
- END;
-
-
- PROCEDURE Parse(CommandLine : STRING; VAR FileName, Params : STRING);
- (* zerlegt eine Kommandozeile in Dateinamen plus Parameterzeile *)
- CONST
- Seperators : SET OF Char = [^I, ' ', ',', '/', ';', '<', '=', '>', '|'];
- VAR
- k : WORD;
- BEGIN
- WHILE CommandLine[1] = ' ' DO Delete(CommandLine, 1, 1);
- k := 1;
- WHILE NOT(CommandLine[k] IN Seperators) (* Trennzeichen gefunden? *)
- AND (k <= Length(CommandLine)) DO Inc(k);
- FileName := Copy(CommandLine, 1, Pred(k));
- IF k <= Length(CommandLine) THEN
- Params := Copy(CommandLine, k, Length(CommandLine))
- ELSE
- Params := '';
- END;
-
-
- PROCEDURE Error(ErrorMessage : STRING);
- (* gibt Fehlermeldung plus -signal aus und wartet auf Tastendruck <Esc> *)
- VAR
- k : BYTE;
- Key : WORD;
-
- PROCEDURE Beep(Hz, MS : WORD);
- (* erzeugt einen Ton der Frequenz "Hz" und der Länge "MS" Millisekunden *)
- BEGIN
- Sound(Hz); Delay(MS); NoSound;
- END;
-
- BEGIN
- Inform(ErrorMessage+'. Weiter mit <Esc>');
- FOR k:=1 TO 2 DO BEGIN
- Beep(600, 40); Beep( 400, 40); Beep(1000, 40);
- Beep(400, 40); Beep(1200, 40); NoSound; Delay(5)
- END;
- REPEAT Key:=GetKey UNTIL Key=Esc; (* auf Escape warten *)
- END;
-
-
- PROCEDURE ErrorHalt(ErrorMessage : STRING);
- (* Fehlermeldung und Programmabbruch *)
- BEGIN
- Error(ErrorMessage+', Programm muß abgebrochen werden');
- TextMode(LastMode);
- RestoreScreenFrom(MainBuffer);
- GotoXY(SaveX, SaveY);
- Halt;
- END;
-
- (* ---------------------- Abfangen von Heap-Fehlern ------------------------ *)
-
- {$F+}
-
- FUNCTION HeapCheck(Size : WORD) : INTEGER;
- BEGIN
- ErrorHalt('Zu wenig Speicher');
- END;
-
- {$F-}
-
- (* ----------------------------- Hauptprogramm ----------------------------- *)
-
- PROCEDURE UpdateLastEntry;
- (* aktualisiert den letzten Eintrag der Programmliste (Freispeicher) *)
- VAR
- St : STRING;
- FreeSpace : LONGINT;
- MemorySize : WORD ABSOLUTE $0040:$0013; (* Speicherausbau in Kilobytes *)
- BEGIN
- FreeSpace := LONGINT(MemorySize*64-NextPSP) * 16;
- St := ' ' + HexW(NextPSP) + ' Noch frei ' + NumStr(FreeSpace, 6);
- Inc(LastEntry);
- AssignStr(InfoList[LastEntry], St);
- END;
-
-
- PROCEDURE Initialize;
- (* Aufbau des Manager-Fensters und Durchführung von Initialisierungen *)
- VAR
- k : WORD;
- BEGIN
- PickMenu := PickMenu1 + PickMenu2;
- ReleaseMode := FALSE;
- DisplayVectors := FALSE; (* standardmäßig Erklärungen anzeigen *)
- NextPSP := PrefixSeg;
- HeapError := @HeapCheck;
- Assign(BatchFile, BatchFileName);
- Rewrite(BatchFile);
- FOR k:=1 TO ListSize DO InfoList[k] := NIL;
- IF VideoMode = 7 THEN
- VideoSegment := $B000 (* Monochrom-Adapter *)
- ELSE
- VideoSegment := $B800; (* Color-Adapter *)
- SaveScreenTo(MainBuffer);
- SaveX := WhereX; SaveY := WhereY;
- CursorOff; (* Cursor abschalten *)
- SetAttribute(ProgAttr);
- ClrScr; (* Bildschirm aufbauen *)
- SetAttribute(FrameAttr);
- DrawFrame(1, 1, 80, 25, '', 0, Double);
- WriteString(2, 2, Header+'»» '+Version+' «« ', MenuAttr);
- Inform(MainMenu);
- SwitchWindow(List);
- END;
-
-
- PROCEDURE SetupInfoList(DisplayVectors : BOOLEAN);
- (* Aufbau der Infoliste aus der MONITOR-Programmliste *)
- VAR
- St : STRING;
- j, k : BYTE;
- found : BOOLEAN;
-
- FUNCTION MonitorList : POINTER;
- (* liefert einen Zeiger auf die Monitor-Programmliste bzw. bricht ab *)
- VAR
- Address : ^POINTER; (* der nullte Listeneintrag *)
- Linear : LONGINT ABSOLUTE Address; (* lineare Zeigerdarstellung *)
- ID : ^STRING;
- BEGIN
- GetIntVec(IFC, POINTER(Address));
- IF Address = Ptr($0000, $0000) THEN (* Interface-Vektor unbenutzt? *)
- ErrorHalt('Monitor nicht installiert')
- ELSE IF Address = Ptr($FFFF, $FFFF) THEN (* Liste übergelaufen? *)
- ErrorHalt('Listenüberlauf')
- ELSE BEGIN
- ID := Address^;
- IF ID^ = MonitorID THEN BEGIN (* OK, Adresse der Liste übergeben *)
- Inc(Linear, SizeOf(POINTER)); (* Zeiger auf ersten Listeneintrag *)
- MonitorList := Address;
- END ELSE
- ErrorHalt('Monitor nicht installiert');
- END;
- END;
-
- BEGIN
- SwitchWindow(Full);
- IF DisplayVectors THEN
- WriteString(34, 2, 'Vektoren (Erklärung', MenuAttr)
- ELSE
- WriteString(34, 2, 'Erklärung (Vektoren', MenuAttr);
- SwitchWindow(List);
- Move(MonitorList^, ProgramList, ListSize*SizeOf(POINTER));
- LastEntry := 0;
- WHILE ProgramList[Succ(LastEntry)] <> NIL DO BEGIN
- Inc(LastEntry);
- WITH ProgramList[LastEntry]^ DO BEGIN (* Daten aus Liste extrahieren *)
- St := ' ' + HexW(ProgramSeg) + ' '
- + LeftAligned(JustName(ProgramName^), 8)
- + NumStr(ProgramSize+EnvironSize, 9) + ' ';
- IF DisplayVectors THEN BEGIN (* benutzte Vektoren auflisten *)
- j := 0;
- FOR k:=0 TO 255 DO
- IF k IN HookedVectors THEN BEGIN
- IF j <= 9 THEN
- St := St + ' ' + Hex(k)
- ELSE
- IF j = 10 THEN
- St := St + ' ...';
- Inc(j);
- END;
- END
- ELSE BEGIN (* Kommentar anfügen, falls Programm in Pickliste *)
- j := 0;
- found := FALSE;
- WHILE (j < LastPick) AND NOT found DO BEGIN
- Inc(j);
- found := JustName(ProgramName^) = JustName(PickList[j].Name^);
- END;
- IF found AND (PickList[j].Comment <> NIL) THEN
- St := St + ' ' + PickList[j].Comment^;
- END;
- AssignStr(InfoList[LastEntry], St);
- END;
- END;
- UpdateLastEntry; (* Segment und Größe des freien Blocks eintragen *)
- END;
-
-
- PROCEDURE SetupPickList; (* Einlesen und Aufbauen der Pickliste *)
- VAR
- PickFile : Text;
- St, n, p : STRING;
- BEGIN
- FOR LastPick:=1 TO PickSize DO (* Pickliste vollständig löschen *)
- WITH PickList[LastPick] DO BEGIN
- Name := NIL;
- Params := NIL;
- Comment := NIL;
- END;
- LastPick := 0; (* Pickliste ist leer! *)
- Assign(PickFile, PickFileName);
- Reset(PickFile);
- IF IoResult <> 0 THEN BEGIN
- Error('Pick-File nicht gefunden');
- Inform(MainMenu);
- END ELSE BEGIN (* Pickliste einlesen *)
- WHILE NOT EoF(PickFile) DO BEGIN
- ReadLn(PickFile, St);
- IF St <> '' THEN BEGIN
- Inc(LastPick);
- WITH PickList[LastPick] DO BEGIN
- Selected := FALSE;
- Parse(St, n, p);
- AssignStr(Name, n);
- IF p <> '' THEN
- AssignStr(Params, p);
- IF NOT EoF(PickFile) THEN BEGIN
- ReadLn(PickFile, St);
- IF St <> '' THEN
- AssignStr(Comment, St);
- END;
- END;
- END;
- END;
- Close(PickFile);
- END;
- END;
-
-
- PROCEDURE ToggleDisplayMode; (* Anzeigewechsel: Vektoren/Erklärung *)
- BEGIN
- DisplayVectors := NOT DisplayVectors;
- SetupInfoList(DisplayVectors);
- RedrawScrollArea; (* Bildschirm neu ausgeben *)
- END;
-
-
- PROCEDURE PickChoice;
- (* Auswahl aus der Pickliste zum Laden von residenten Programmen *)
- VAR
- MainListArea : ScrollPB;
- Aborted : BOOLEAN;
- j, k, Key : WORD;
- BEGIN
- Rewrite(BatchFile);
- IF LastPick = 0 THEN Exit; (* Pickliste ist leer! *)
- SaveScreenTo(TempBuffer);
- Inform(PickMenu);
- SaveScrollArea(MainListArea);
- SwitchWindow(Pick);
- SetupScrollArea(LastPick, @WriteNormalPick, @WriteSelectedPick);
- ScrollResponse(Home);
- Aborted := FALSE;
- REPEAT
- Key := GetKey;
- ScrollResponse(Key);
- CASE Key OF
- Left,
- Right : BEGIN
- PickList[SelectIndex].Selected := (Key = Right);
- WriteSelectedPick(1, Succ(SelectIndex-TopIndex), SelectIndex);
- ScrollResponse(Down);
- END;
- Return : Quit := TRUE;
- Esc : Aborted := TRUE;
- END;
- UNTIL Quit OR Aborted;
- RestoreScreenFrom(TempBuffer);
- IF NOT Aborted THEN BEGIN (* es soll etwas geladen werden! *)
- j := 0;
- FOR k:=1 TO LastPick DO (* Pickliste nach Selekt-Marken abchecken *)
- WITH PickList[k] DO
- IF Selected THEN BEGIN
- Write(BatchFile, Name^);
- IF Params <> NIL THEN (* Kommandoparameter vorhanden? *)
- Write(BatchFile, Params^);
- WriteLn(BatchFile);
- Inc(j);
- END;
- IF j = 0 THEN (* keine Marken gesetzt: Balken ist Marke *)
- WITH PickList[SelectIndex] DO BEGIN
- Write(BatchFile, Name^);
- IF Params <> NIL THEN (* Kommandoparameter vorhanden? *)
- Write(BatchFile, Params^);
- WriteLn(BatchFile);
- END;
- END ELSE
- RestoreScrollArea(MainListArea); (* alten Zustand wiederherstellen *)
- END;
-
-
- PROCEDURE ReleaseTSRs;
- (* Auswahl, welche residenten Programme wieder gelöscht werden sollen *)
- VAR
- Key : WORD;
-
- PROCEDURE RestoreVectors;
- (* von einem Programm benutzte Vektoren restaurieren *)
- VAR
- j, v : BYTE;
- BEGIN
- j := 0;
- FOR v:=0 TO $FF DO
- WITH ProgramList[LastEntry]^ DO
- IF v IN HookedVectors THEN BEGIN
- SetIntVec(v, SavedVectors^[j]);
- Inc(j);
- END;
- END;
-
- PROCEDURE ReleaseMemory(Segment : WORD);
- (* gibt den von DOS belegten Speicherblock bei "Segment" wieder frei *)
- VAR
- Regs : Registers;
- BEGIN
- WITH Regs DO BEGIN
- ES := Segment;
- AH := $49; (* DOS-Funktion "Free Allocated Memory" *)
- MsDos(Regs);
- IF Odd(Flags) THEN BEGIN
- Error('Fehler bei Freigabe von Block ' + HexW(Segment));
- Inform(ReleaseMenu);
- END;
- END
- END;
-
- BEGIN
- ReleaseMode := TRUE;
- DisposeStr(InfoList[LastEntry]); (* Freispeicher-Eintrag entfernen *)
- Dec(LastEntry);
- Dec(LinesToScroll);
- SetAttribute(ProgAttr); ClrScr;
- Inform(ReleaseMenu);
- ScrollResponse(End_);
- REPEAT (* Scrollroutine dient jetzt zur Lösch-Anwahl! *)
- Key := GetKey;
- IF Key = Tab THEN
- ToggleDisplayMode
- ELSE
- ScrollResponse(Key);
- UNTIL (Key = Esc) OR (Key = Return);
- IF Key = Return THEN BEGIN (* markierte Programme entfernen *)
- WHILE LastEntry >= SelectIndex DO (* Programm löschen? *)
- WITH ProgramList[LastEntry]^ DO
- IF JustName(ProgramName^) <> JustName(ComSpecName) THEN BEGIN
- RestoreVectors; (* Interruptvektoren restaurieren *)
- ReleaseMemory(ProgramSeg); (* Programmspeicher freigeben *)
- IF EnvironSize <> 0 THEN
- ReleaseMemory(EnvironSeg); (* Environment freigeben *)
- NextPSP := ProgramSeg;
- DisposeStr(InfoList[LastEntry]); (* aus Liste entfernen *)
- ProgramList[LastEntry] := NIL;
- IF LastEntry = 1 THEN BEGIN (* MONITOR gelöscht? *)
- Quit := TRUE; Exit; (* dann sofort Programm beenden *)
- END;
- Dec(LastEntry);
- END ELSE BEGIN
- Error('Löschen außerhalb aktueller DOS-Umgebung nicht möglich');
- SelectIndex := Succ(LastEntry);
- END;
- END;
- UpdateLastEntry; (* Segment und Größe des freien Blocks eintragen *)
- ReleaseMode := FALSE;
- SetAttribute(ProgAttr); ClrScr;
- LinesToScroll := LastEntry; (* neuen Listenumfang bekanntmachen *)
- ScrollResponse(End_);
- END;
-
-
- BEGIN (* Manager-Hauptprogramm *)
- Initialize;
- SetupPickList;
- SetupInfoList(DisplayVectors);
- SetupScrollArea(LastEntry, @WriteNormalTSR, @WriteSelectedTSR);
- ScrollResponse(End_);
- Quit := FALSE;
- REPEAT
- Key := GetKey;
- ScrollResponse(Key);
- CASE Key OF
- Tab : ToggleDisplayMode;
- Ins,
- Del : BEGIN
- IF Key = Ins THEN
- PickChoice
- ELSE
- ReleaseTSRs;
- Inform(MainMenu);
- END;
- Esc : Quit := TRUE;
- END;
- UNTIL Quit; (* bis <Esc> gedrückt oder MONITOR gelöscht! *)
- Close(BatchFile);
- TextMode(LastMode);
- RestoreScreenFrom(MainBuffer);
- GotoXY(SaveX, SaveY);
- END.
- (* ------------------------------------------------------------------------- *)
- (* Ende von MANAGER.PAS *)