home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* ZEITMESS.PAS *)
- (* Zeitmessung im Mikrobereich *)
- (* (c) 1989 Ulrich Telle & TOOLBOX *)
- (* ------------------------------------------------------ *)
- {$B-,I-,R-,S-,V-,N+} { damit's schneller geht... }
-
- UNIT ZeitMess;
-
- INTERFACE
-
- TYPE SuperZeit = ARRAY[1..3] OF WORD;
-
- { Prozeduren und Funktionen für SuperZeit-Manipulationen }
- { Beschreibung im Implementationsteil }
-
- PROCEDURE ZeitProlog;
- PROCEDURE ZeitEpilog;
- PROCEDURE ZeitLesen(VAR t : SuperZeit);
- FUNCTION ZeitWandeln(t : SuperZeit) : EXTENDED;
- FUNCTION ZeitDauer(Start, Stop : SuperZeit) : EXTENDED;
- FUNCTION ZeitDauerString(Start, Stop : SuperZeit) : STRING;
- FUNCTION UhrZeit : STRING;
-
- IMPLEMENTATION
-
- CONST
- PIC = $20; { 8259 }
- TimerC = $43; { 8253 Kontrolle }
- Timer0 = $40; { 8253 Zähler 0 }
- TimerMode2 = $34; { 8253 Modus 2 }
- TimerMode3 = $36; { 8253 Modus 3 }
- TimerTicks = 1193.182; { 8253 Taktfrequenz pro msec }
-
- VAR
- Korrektur : EXTENDED; { Korrektur für Stopuhr }
- ExitProcAlt : POINTER; { Zeiger auf alte Exit-Prozedur }
-
- PROCEDURE ZeitProlog;
- { Zeitgeber-Baustein 8253 auf Modus 2 setzen }
- BEGIN
- Port [TimerC] := TimerMode2;
- Port [Timer0] := 0;
- Port [Timer0] := 0;
- END;
-
- PROCEDURE ZeitEpilog;
- { Zeitgeber-Baustein 8253 auf Modus 3 setzen }
- BEGIN
- Port [TimerC] := TimerMode3;
- Port [Timer0] := 0;
- Port [Timer0] := 0;
- END;
-
- PROCEDURE ZeitLesen (VAR t : SuperZeit);
- VAR
- irr, b1, b2 : BYTE;
- BEGIN
- INLINE($FA); { CLI }
- Port[PIC] := $0A; { Anforderung an den }
- { Interrupt-Controller, Auslesen }
- { des Interrupt Request Registers }
- Port[TimerC] := 0; { Zählerstand in 8253 Register }
- irr := Port[PIC]; { IRR lesen }
- b1 := Port[Timer0]; { niederwertiger Zählerstand }
- b2 := Port[Timer0]; { höherwertiger Zählerstand }
- t[2] := MemW[$0040:$006C];
- { niederwertiger DOS-Zeitzähler }
- t[3] := MemW[$0040:$006E];
- { höherwertiger DOS-Zeitzähler }
- INLINE($FB); { STI }
- t[1] := NOT (word(b2) SHL 8 + b1);
- { Zählerstand des Timers }
- IF Odd(irr) AND (t[1] < 128) THEN BEGIN
- { Korrektur, wenn Timer-Interrupt }
- Inc(t[2]); { anliegt }
- IF t[2] = 0 THEN Inc(t[3]);
- END;
- END;
-
- FUNCTION ZeitWandeln (t : SuperZeit) : EXTENDED;
- VAR
- treal : EXTENDED;
- j : INTEGER;
- BEGIN
- treal := 0.0;
- FOR j := 3 DOWNTO 1 DO
- treal := treal * 65536.0 + t[j];
- ZeitWandeln := treal / TimerTicks;
- END;
-
- FUNCTION ZeitDauer (Start, Stop : SuperZeit) : EXTENDED;
- BEGIN
- ZeitDauer := ZeitWandeln(Stop) - ZeitWandeln(Start)
- - Korrektur;
- END;
-
- FUNCTION ZeitDauerString(Start, Stop: SuperZeit) : STRING;
- VAR
- tstr : STRING;
- BEGIN
- Str(ZeitDauer(Start, Stop):0:3, tstr);
- ZeitDauerString := tstr;
- END;
-
- FUNCTION UhrZeit : STRING;
- VAR
- t : SuperZeit;
- treal : EXTENDED;
- tint : LONGINT;
- tstr1, tstr2 : STRING[20];
- BEGIN
- ZeitLesen(t);
- treal := ZeitWandeln(t);
- Str(treal:0:3, tstr1); { Milli- und Mikrosekunden }
- tstr1 := Copy(tstr1, Length(tstr1)-6, 7);
- tint := Trunc(treal / 1000.0); { Sekunden }
- Str((tint MOD 60):2, tstr2);
- IF tstr2[1] = ' ' THEN tstr2[1] := '0';
- tstr1 := tstr2 + ',' + tstr1;
- tint := tint DIV 60; { Minuten }
- Str((tint mod 60):2, tstr2);
- if tstr2[1] = ' ' THEN tstr2 := '0';
- tstr1 := tstr2 + ':' + tstr1;
- Str(tint DIV 60, tstr2); { Stunden }
- UhrZeit := tstr2 + ':' + tstr1;
- END;
-
- PROCEDURE ZeitEichen;
- CONST
- Anzahl = 500; { Magische Zahl (vom Himmel gefallen) }
- VAR
- j : INTEGER;
- t1, t2 : SuperZeit;
- Differenz : EXTENDED;
- BEGIN
- Korrektur := 1.0E+10;
- FOR j := 1 TO Anzahl DO BEGIN
- ZeitLesen(t1);
- ZeitLesen(t2);
- Differenz := ZeitWandeln(t2) - ZeitWandeln(t1);
- IF Differenz < Korrektur THEN Korrektur := Differenz;
- END;
- END;
-
- {$F+} { WICHTIG für Exit-Prozeduren }
- PROCEDURE ZeitMessExit;
- BEGIN
- ExitProc := ExitProcAlt;
- ZeitEpilog;
- END;
- {$F-}
-
- BEGIN { Unit-Initialisierung }
- ExitProcAlt := ExitProc; { Exit-Prozedur merken }
- ExitProc := @ZeitMessExit; { und eigene setzen }
- ZeitProlog; { ZeitMess initialisieren }
- ZeitEichen; { Korrekturterm bestimmen }
- END.
- (* ------------------------------------------------------ *)
- (* Ende von ZEITMESS.PAS *)