home *** CD-ROM | disk | FTP | other *** search
- (* ----------------------------------------------------------------------- *)
- (* DUMP.PAS *)
- (* Datei-Inhalt als (HEX-) DUMP *)
- (* Das Programm gibt den Inhalt einer Datei als DUMP auf die Ausgabe aus.
- Der Aufruf kann mit DUMP Filename /Optionen erfolgen. Die Eingabe der
- Optionen ist nicht zwingend erforderlich. Es sollte immer nur der erst
- Buchstabe der Option eingegeben werden. Der Aufruf kann in folgender
- Form erfolgen:
- >DUMP Dateiname.ext -Optionen
- Wird nur DUMP eingegeben, werden Filename und Optionen explizit erfragt:
- Datei : DUMP.PAS
- Option : -ab...
- Es stehen folgende Optionen zur Verfuegung:
- -A ASCII: Anzeige nur ASCII Zeichen
- -K KeinASCII: Anzeige nur Dump Zeile
- -N Normal: 1 Zeile Dump, 1 Zeile ASCII
- -B Breit: ASCII Darst. hinter Dump
- -M Mehr: Unterbrechung alle n Zeilen
- -H Base = hex. -O Base = okt. -D Base = dez.
- -C Ausgabe auf Console -P Ausgabe auf Printer
- Standardmaessig wird -NHCM eingestellt. Die Mehr-Option ist nur im Con-
- sole-Mode aktiv. Die Printer-Option erzeugt eine seitenorientierte Dar-
- stellung mit einer Kopfzeile und Seitennummerierung. *)
- (* ----------------------------------------------------------------------- *)
-
- PROGRAM Dump (Input, Output, InFile, OutFile);
-
- CONST
- Word_Len = 2; (* Laenge Word *)
- Byte_Len = 1; (* " Byte *)
- Max_Column = 16; (* 16 Werte pro Zeile *)
- Max_Column_ascii = 60; (* 60 " bei Ascii *)
- Max_Screen = 20; (* Zeilen pro Screen *)
- Page_Length = 65; (* " " Seite *)
- Space_Wide = ' ';
- CR = 10; (* ASCII: Carriage Return *)
- LF = 13; (* " : Line Feed *)
- FF = 12; (* " : Form Feed *)
- BufSize = 128; (* 128 Bytes Einlese-Puf. *)
-
- TYPE File_Name_Typ = STRING[65];
- File_Typ_Byte = FILE OF BYTE; (* fuer CP/M: nur "FILE" !! *)
- Zahlen_System = (hex,okt,dez);
- Modus = (ascii,compressed,normal,wide);
-
- VAR
- Row, Adr, i,
- Max_Spalte,
- Line_step,
- Line, Page,
- BufPos, (* Position im Einlese-Puffer *)
- EOFPos : INTEGER; (* Position des letzten Bytes im Puffer *)
- Code : ARRAY [1..Max_Column_ascii] OF BYTE;
- Buffer : ARRAY [1..BufSize] OF BYTE;
- more,
- EndOfFile : BOOLEAN;
- Space_Pred : STRING [2];
- Space_Suc : STRING [2];
- Space_Zeilen_Anfang : STRING [7];
- Space_Code_Base : STRING [4];
- End_Line : STRING [8];
- Mode : STRING [10];
- HexZif : ARRAY [0..15] OF CHAR;
- Base : Zahlen_System;
- Switch : Modus;
- File_Name : File_Name_Typ;
- InFile : File_Typ_Byte;
- Device : STRING [4];
- OutFile : TEXT;
-
- (* ----------------------------------------------------------------------- *)
- (* Ausgabe eines Wertes als Zahl auf der Standardausgabe. Durch Len wird
- festgelegt, ob ein Byte (Len = 1) oder Wort (Len = 2) ausgegeben werden
- soll. Das Format wird durch die eingestellte Basis bestimmt => Hex xx
- oder xxxx. Die hier verwendeten Turbo-Funktionen 'Lo' und 'Hi' liefern
- jeweils das nieder- bzw. hoeherwertige Byte einer Integer-Zahl. Implemen-
- tations-Vorschlag: Lo := value MOD 256; Hi := value DIV 256 *)
-
- PROCEDURE Write_val (value, len : INTEGER);
-
- VAR temp, carry : INTEGER;
-
- BEGIN
- CASE Base OF
- hex: BEGIN (* Format : High Low Byte
- xxxx xxxx Hex -> xx = 4 bit pro Ziffer *)
- IF len = Word_Len THEN
- BEGIN
- temp := Hi (value);
- Write (OutFile,HexZif[temp DIV 16]:1,HexZif[temp MOD 16]:1);
- END;
- temp := Lo (value);
- Write (OutFile,HexZif[temp DIV 16]:1,HexZif[temp MOD 16]:1,' ');
- END;
- okt: BEGIN (* Format : High Byte Low Byte a..f = bits
- abbb cccd ddee efff 3 bit pro Ziffer *)
- carry := 0;
- IF len = Word_Len THEN
- BEGIN
- temp := Hi (value);
- Write (OutFile,(temp DIV 128):1);
- Write (OutFile,(temp AND 112) DIV 16:1);
- Write (OutFile,(temp AND 14) DIV 2:1);
- IF Odd (temp) THEN carry := 256;
- END;
- temp := Lo (value) + carry;
- Write (OutFile,(temp DIV 64):1);
- Write (OutFile,(temp AND 56) DIV 8:1);
- Write (OutFile,(temp AND 7):1,' ');
- END;
- dez: BEGIN
- IF len = Word_Len THEN Write (OutFile,value:5,' ')
- ELSE Write (OutFile,value:3,' ');
- END;
- END; { case }
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Ausgabe der n Codewerte in einer Zeile. Bei korrekter Einstellung wer-
- den die ASCII-Aequivalente im zweiten Schritt ausgegeben. *)
-
- PROCEDURE Write_line;
-
- VAR i : INTEGER;
-
- BEGIN
- Write_val (Adr,Word_Len); (* Adresse ausgeben *)
- IF Switch <> ascii THEN (* Hex-, Okt- oder Dez-Werte ausgeben *)
- BEGIN
- FOR i := 1 TO Row DO Write_val (Code[i],Byte_Len);
- Write (OutFile,End_Line); (* Cursor in n. Zeile oder nur Blanks *)
- END;
- IF Switch <> compressed THEN (* als Text ausgeben *)
- BEGIN
- IF Switch = wide THEN
- BEGIN
- FOR i:= Row + 1 TO Max_Spalte DO Write (OutFile,Space_Code_Base);
- Write (OutFile,Space_Wide);
- END
- ELSE
- Write (OutFile,Space_Zeilen_Anfang);
- FOR i := 1 TO Row DO
- IF Code[i] IN [32..126] THEN (* druckbares Zeichen ? *)
- Write (OutFile,Space_Pred,Chr(Code[i]),Space_Suc)
- ELSE
- Write (OutFile,Space_Pred,'.',Space_Suc);
- WriteLn (OutFile);
- END;
- Line := Line + Line_step;
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Versuche, Datei zu oeffnen *)
-
- FUNCTION Open(VAR fp:File_Typ_Byte; File_Name: File_Name_Typ): BOOLEAN;
-
- BEGIN
- Assign(fp,File_Name); (* andere Dialekte: entfaellt, s.u.: ReSet *)
- {$I-} (* Turbo-I/O-Fehlerbehandlung durch Laufzeitsystem auschalten *)
- ReSet(fp); (* andere Dialekte: ReSet(fp, File_Name) *)
- {$I+} (* Fehlerbehandlung durch Laufzeitsystem wieder aktiv *)
- IF IOResult <> 0 THEN (* wenn <> 0 trat ein Fehler bei ReSet auf... *)
- BEGIN Open := FALSE; Close(fp); END (* ja, "Close" schliesst wieder *)
- ELSE
- Open := TRUE;
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Einstellung der Standard-Optionen *)
-
- PROCEDURE Init;
-
- VAR i: INTEGER;
-
- BEGIN
- WriteLn; WriteLn;
- Device := 'CON:'; (* Ausgabe auf Console *)
- Base := hex;
- Switch := normal;
- Space_Code_Base := ' '; (* 3 blanks *)
- End_Line := Chr(CR) + Chr(LF);
- Space_Pred := ' ';
- Space_Suc := ' ';
- Space_Zeilen_Anfang := ' '; (* 4 Blanks *)
- Space_Code_Base := ' '; (* 3 Blanks *)
- Max_Spalte := Max_Column; Line := 0; Page := 1; more := TRUE;
- FOR i := 0 TO 9 DO HexZif[i] := Chr(Ord('0')+i);
- FOR i := 10 TO 15 DO HexZif[i] := Chr(Ord('A')-10+i);
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* pruefe, ob Parameter und Filename vom Betriebssystem uebergeben wurde,
- sonst frage sie ab und setze die neuen Optionen *)
-
- PROCEDURE get_parameter;
-
- VAR i : INTEGER;
-
- BEGIN
- IF ParamCount = 0 THEN (* wieviel Parameter in Kommandozeile ? *)
- BEGIN (* keine -> jetzt erfragen: *)
- WriteLn ('Optionen: ASCII KeinASCII Normal Breit Mehr ');
- WriteLn (' Printer Console Hex Oct Dez ');
- WriteLn;
- Write (' Datei: '); ReadLn (File_Name);
- Write ('Option: '); ReadLn (Mode);
- WriteLn;
- END
- ELSE (* Parameter aus Kommandozeile holen. Falls dies im Pascal- *)
- BEGIN (* Dialekt nicht moeglich, nur oberen Dialog-Teil verwenden! *)
- File_Name := ParamStr(1); (* 1. Parameter: anzusehende Datei *)
- IF ParamCount > 1 THEN Mode := ParamStr(2); (* Optionen angegeben ? *)
- IF ParamCount > 2 THEN
- BEGIN
- WriteLn ('**** zu viel Parameter...');
- WriteLn ('**** Gebrauch: "DUMP Dateiname.ext -Optionen" ',
- ' oder einfach "DUMP" !');
- Halt; (* Programm abbrechen! *)
- END;
- END;
- FOR i := 1 TO Length (Mode) DO Mode[i] := UpCase (Mode[i]);
- (* pruefe, welche Optionen gesetzt wurden und aktiviere sie. *)
- IF Pos ('O',Mode) <> 0 THEN (* Pos sucht 'O' im String 'mode' *)
- BEGIN
- Base := okt;
- Space_Pred := ' '; (* 2 Blanks *)
- Space_Zeilen_Anfang := ' '; (* 7 Blanks *)
- Space_Code_Base := ' '; (* 4 Blanks *)
- END
- ELSE IF Pos('D',Mode) <> 0 THEN
- BEGIN
- Base := dez;
- Space_Pred := ' '; (* 2 Blanks *)
- Space_Zeilen_Anfang := ' '; (* 6 Blanks *)
- Space_Code_Base := ' '; (* 4 Blanks *)
- END;
- IF Pos ('A',Mode) <> 0 THEN
- BEGIN
- Switch := ascii;
- Space_Pred := ''; (* keine Leerzeichen zwischen den Buchstaben *)
- Space_Suc := '';
- Max_Spalte := Max_Column_ascii;
- END
- ELSE IF Pos('K',Mode) <> 0 THEN
- BEGIN Switch := compressed END
- ELSE IF Pos ('B',Mode) <> 0 THEN
- BEGIN
- Switch := wide; Space_Pred := ''; Space_Suc := ''; End_Line := '';
- END;
- IF Pos ('P',Mode) <> 0 THEN (* Ausgabe auf Drucker *)
- BEGIN Device := 'LST:'; Line := Page_Length + 1; more := FALSE; END;
- IF Pos ('M',Mode) <> 0 THEN more := FALSE;
- IF Switch = normal THEN Line_step := 2 (* 2 Zeilen Ausdruck *)
- ELSE Line_step := 1;
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* ein Byte aus der Datei lesen. Um mit CP/M kompatibel zu sein, werden
- 128 Bytes in einen Buffer gelesen und dann Byte fuer Byte an das Pro-
- gramm weitergegeben. Siehe Kommentare hier und bei der TYPE-Definition. *)
-
- PROCEDURE Get_Byte (VAR f: File_Typ_Byte; VAR byt: BYTE);
-
- PROCEDURE FillBuf;
- VAR i: INTEGER;
- BEGIN
- (* fuer CP/M:
- BlockRead(f, buffer, 1);
- IF eof(f) then EOFPos := BufSize;
- *)
- (* fuer MS-DOS und Pascal ohne BlockRead: *)
- i := 0;
- REPEAT i := Succ(i); Read (f, Buffer[i]); UNTIL Eof(f) OR (i = 128);
- IF Eof(f) THEN EOFPos := i;
- (* *)
- END;
-
- BEGIN
- BufPos := Succ(BufPos);
- IF BufPos > BufSize THEN BEGIN BufPos := 1; FillBuf; END;
- byt := Buffer[BufPos];
- IF EOFPos > 0 THEN IF BufPos = EOFPos THEN EndOfFile := TRUE;
- END;
-
- (* ----------------------------------------------------------------------- *)
-
- BEGIN
- EndOfFile := FALSE; BufPos := BufSize; EOFPos := -1;
- Init;
- WriteLn ('DUMP 1.0 (C) Born & PASCAL International');
- WriteLn;
- get_parameter;
- Assign (OutFile,Device); (* Ausgabe-Datei oeffnen *)
- ReWrite (OutFile);
- IF NOT Open(InFile,File_Name) THEN
- BEGIN
- WriteLn('Fehler: Datei "',File_Name,'" nicht gefunden !');
- Halt;
- END;
- Row := 0; Adr := 0;
- WHILE NOT EndOfFile DO
- BEGIN
- Row := Row + 1;
- IF Pos ('P',Mode) <> 0 THEN
- IF Line >= Page_Length THEN
- BEGIN
- Write(OutFile,Chr(FF),'Datei : ',File_Name,' ');
- WriteLn (OutFile,' Seite :',Page); WriteLn;
- Page := Page + 1; Line := 1;
- END;
- Get_Byte (InFile,Code[Row]);
- IF Row = Max_Spalte THEN
- BEGIN
- Write_line; Adr := Adr + Max_Spalte; Row := 0;
- END;
- IF more THEN
- BEGIN
- IF Line >= Max_Screen THEN
- BEGIN
- WriteLn; WriteLn ('Mehr - eine Taste druecken...');
- REPEAT UNTIL KeyPressed;
- Line := 0; WriteLn;
- END;
- END;
- END; (* WHILE *)
- Write_line;
- Close (InFile);
- Close (OutFile);
- END.
-