ALICE Pascal ist ein PASCAL Interpreter. Es gibt ihn für den IBM-PC und den ATARI ST. Und er ist einzigartig. Lesen Sie warum.
Angesichts der unübersichtlichen Fülle von Computersprachen, erhebt sich gerade für den Neuling die Frage, mit welcher Sprache er seine ersten Schritte im fremden Computerland unternehmen soll. Fragt man einen alten Hasen nach seiner Meinung, so erhält man bei n befragten Personen 2n+l Antworten, je nach Einstellung und Vorbildung des Befragten. Eines steht aber fest: Das serienmäßig mit dem ST ausgelieferte BASIC ist so schlecht, daß man besser gleich einen anderen Interpreter (oder Compiler) mitkauft. Und wenn man seinem Geldbeutel schon diese Entscheidung abgerungen hat, dann taucht brennend die eingangs gestellte Frage auf: Mit welcher Sprache beginnen? BASIC ist zwar Standard, die Microsoft Derivate (incl. ST-BASIC) leiden aber an chronischem Mangel moderner Programmierelemente wie Rekursion, lokalen Variablen, Prozeduren und Funktionen. Rühmliche Ausnahmen bilden da GFA- und OMIKRON. BASIC. Fragt man die Herren von der pädagogischen Zunft, so ist meist PASCAL die Antwort auf die Frage nach der Wahl. In der Tat besitzt PASCAL alles was eine moderne (imperative) Programmiersprache braucht und was für das weitergehende Verständnis anderer Sprachen benötigt wird. Leider aber ist der Einstieg für Anfänger so ungeheuer schwer. Tastenverbieger der anfangenden Art haben ja im allgemeinen noch Schwierigkeiten mit der Bedienung der vielen Knöpfe. Und dann sollen auch noch möglichst gleichzeitig die verschiedenen Komponenten eines PASCAL Systems bedient werden als da sind Editor, Compiler, Linker. Kein Wunder, daß sich PASCAL als Anfängersprache immer wieder das Entsetzen der Anfänger zuzieht, bis irgendwann der Knoten platzt und aus Haß Liebe wird. Gewiß, mit TURBO-PASCAL (das in den Schulen stark verbreitet ist) ist der PASCAL Schock stark gemindert worden, aber mit Sehnsucht denkt jeder Anfänger an sein BASIC zu Hause. In dieses Szenario tritt nun mit Fanfaren ALICE, der erste (und meines Wissens einzige) PASCAL Interpreter. Man glaubt seinen Augen nicht zu trauen: PASCAL so einfach zu bedienen wie BASIC?
ALICE kommt auf 2 einseitig formatierten Disketten (nicht kopiergeschützt) mit 2 Handbüchern. Das erste Handbuch ist ein Tutorial zur Bedienung von ALICE. Das zweite Handbuch ist das detaillierte Nachschlagewerk für den Programmierer. Um einen Eindruck von ALICE zu bekommen, kann man getrost auf das Lesen der (englischsprachigen) Handbücher verzichten. Man legt die erste Diskette ein und startet ALICE.PRG. Auf dem Bildschirm erscheint Abb.1. Ja, Sie haben richtig gesehen. Bereits mit dem Start des Interpreters wird die Schablone eines PASCAL-Programms vorgegeben. An diesem Bild können Sie das Arbeitsprinzip von ALICE bereits erkennen, das im folgenden konsequent eingehalten wird. Der ALICE-Editor ist ein an der PASCAL Syntax orientiertes Programm, das keinen Text editiert, sondern die Substitution von Schablonen in PASCAL Termen ermöglicht. Klingt hochgestochen, ist aber ganz einfach. Gehen wir von Abb.1 aus und lassen Sie uns die Entstehung des einfachen Programms verfolgen. Als erstes wollen wir dem Programm einen Namen geben. Dazu gehen wir mit dem Cursor auf die Schablone für den Programmnamen. Man erkennt Schablonen am Unterstreichungsmodus in Abb.1. Es ist egal, wo der Cursor steht, solange er nur irgendwo auf der Schablone steht.
Sobald Sie jetzt beginnen den Namen zu tippen, verschwindet die Schablone und wird durch ihre Eingabe ersetzt. Noch ist die Eingabe nicht akzeptiert, was man an der gestrichelten Unterstreichung des eingegebenen Textes erkennt. Ist der Text eingegeben, überprüft ALICE die Eingabe sofort auf korrekte Syntax und Semantik. Wer etwa versucht, in einer Variablendeklaration eine Konstante zu vereinbaren, wird darauf hingewiesen, das ALICE an dieser Stelle des Textes eben eine Variablendeklaration erwartet und nicht die Definition einer Konstanten. Eingeleitet wird diese Überprüfung, in dem man den Cursor von der Schablone entfernt. Im Normalfall verschwindet nun die Unterstreichung, woran man erkennt, daß ALICE keinen Fehler entdeckt hat. Abb.2 zeigt diesen Vorgang im Detail. Das Entfernen des Cursors von der Schablone erfolgt entweder mit den Cursortasten oder mit der RETURN-Taste oder mit der TAB-Taste. Eine Betätigung der Cursortasten bewirkt nichts, außer der erwähnten Überprüfung durch ALICE. Betätigung der RETURN-Taste erzeugt zusätzlich eine neue Schablone der an dieser Stelle zulässigen semantischen Struktur. Auf diese Art wird man sein Programm aufbauen. Mit der TAB-Taste springt man von Schablone zu Schablone vorwärts, überspringt also die PASCAL Schlüsselworte. Fahren wir fort in der Erstellung unseres Programms. Wir wollen einer Variablen i einen Wert zuweisen und diesen ausdrucken. Als nächstes steht also die Deklaration einer Variablen auf dem Plan. Also Cursor auf die Declarations-Schablone stellen, var eintippen, Leertaste betätigen und ... die komplette Schablone einer Variablendeklaration steht ausfüllbereit im Editor. Abb.3 zeigt diesen Vorgang wiederum im Detail. Egal welche Anweisung sie eintippen, stets unterliegen Sie der liebevollen Überwachung der großen Schwester ALICE, die sie freundlich aber unnachgiebig auf ihre Fehler hinweist. Es ist einem Anfänger damit wohl unmöglich gemacht worden, die üblichen Fehler zu begehn, wie vergessene Semicolons (ersetzt ALICE selbständig für Sie), Gleichheitszeichen statt Doppelpunkt in einer Variablendeklaration und dergleichen Nadelstiche alter PASCAL Implementationen mehr. Und sollten Sie eine Variable, Funktion oder Prozedur benutzen, die sie bislang noch nicht deklariert haben, so markiert ALICE diese treu und brav, bis sie endlich ihrer vernachlässigten Pflicht nachgekommen sind. Allerdings hat diese strenge Orientierung an der PASCAL Syntax auch ihre Nachteile. Stellen Sie sich vor, Sie haben in einer IF-Anweisung die Bedingung stehen i<j und wollen diese ändern in i< =j. Dazu gehen Sie mit dem Cursor auf die i<j Bedingung, markieren diese und löschen Sie vollständig, worauf die Condition-Scha-blone wieder auftaucht. Dann ersetzen Sie die Condition-Schablone wieder durch die i < = j Bedingung. Das kann im Extremfall zu einer erheblichen Tipparbeit ausarten. Für solche Fälle stellt ALICE zwar die Möglichkeit zur Verfügung, eine Schablone wie Text zu bearbeiten, es bleibt in solchen Fällen jedoch eine etwas unkomfortablere Bedienung als mit einem reinen Texteditor.
Tabelle 1: Ausführungszeiten der Benchmarkprogramme in sec.
------ | ST-BASIC | ALICE | PascalPlus | MEGAMAX C |
---|---|---|---|---|
Fibonacci | - | 264 | 2.8 | 1.12 |
Float | 191 | 288 | 51 | 52 |
Erato | 100 | 120 | 0.8 | 0.6 |
Quick | - | 140 | 4 | 4 |
Savage | 53 | 238 | 146 | 288 |
Häufig benutzte Strings lassen sich allerdings zum Ausgleich auch auf beliebige Tasten legen und einfach als Macros wieder abrufen. Es ist auch möglich, ein Programm in ein bestehendes zu mergen. Die Lesbarkeit kann aber darunter leiden, weil dann plötzlich an zwei verschiedenen Stellen Konstanten-, Typen- oder Variablendeklarationen stehen. Besser ist es, von der Möglichkeit Gebrauch zu machen, mehrere Workspaces gleichzeitig zu eröffnen und mit verschiedenen Programmen zu belegen. Sie können dann von einem Programm zum anderen wechseln, indem Sie einfach das entsprechende Fenster anklicken. Auch Kopieren zwischen den Workspaces ist erlaubt. Mit RUN bringen Sie das im aktuellen Workspace befindliche Programm zur Ausführung, die anderen Workspaces ruhen dann.
Nachdem nun Ihr Programm mit Sicherheit syntaktisch einwandfrei im Editor steht, besteht leider immer noch die Möglichkeit, Unsinn programmiert zu haben, d.h. einen fehlerhaften Algorithmus verwendet zu haben. Solchen Fehlern kommt ALICE mit Hilfe seiner vielseitigen DEBUG Möglichkeiten auf die Spur. Es handelt sich bei ALICE wie gesagt um einen Interpreter für PASCAL. Sie können also einzelne Anweisungen markieren und einzeln ausführen lassen. Natürlich funktioneiert das auch mit Programmblöcken. Sie können das Programm im Single Step Modus durchlaufen und die jeweils berechneten Werte mitanzeigen. Und man kann den Cursor im Editorfenster mitlaufen lassen.
In den USA wirbt Looking Glass Software mit der Kompatibilität zu TURBO-PASCAL. In der Tat ist es mir gelungen, eine Reihe von TURBO-PASCAL Programmen auf dem ST unter ALICE zum Laufen zu bringen. Allerdings ist das nicht ganz so problemlos möglich, wie es die Werbung erscheinen läßt. Auf der zweiten Diskette ist ein Programm Namens APIN.PRG, welches die Konversion vornimmt. ALICE-PASCAL Programme werden nämlich nicht als ASCII-Text abgespeichert, sondern in einer komprimierten Form. Aus diesem Grunde erhalten ALICE-Programme die Extension .AP. Die ersten Versuche, Turbo Programme zu konvertieren, scheiterten. APIN druckte eine Fehlermeldung aus und kehrte zum Desk-top zurück, ohne dem Benutzer die Chance zu geben, die Fehlermeldung zu lesen. Nach mehreren Versuchen stellte sich dann heraus, daß APIN den Ersatz (. .) für [ ], bzw. (.*) für nicht mochte. Nach der entsprechenden Änderung mit Hilfe eines Texteditors klappte die *.PAS - > *.AP Umwandlung dann problemlos. Auch Programme mit IBM-PC Grafik wurden problemlos übersetzt, bedurften allerdings noch geringfügiger Nachbehandlung wegen der Fensterbehandlung und unterschiedlicher Grafikauflösung. Mit etwas Übung sollte einem damit die Konversion von Turbo-Pascal Programmen auf dem ST unter CEM keine Probleme bereiten. Im OPTIONS-Menü läßt sich ALICE im übrigen auf TURBO-Pascal Syntax oder Standard-Pascal Syntax voreinstellen. Dennoch bleiben ein Paar Inkompatibilitäten, vornehmlich im I/O-Bereich, die sich jedoch an Hand der ausführlichen Dokumentation im Handbuch problemlos beseitigen lassen. Ich erinnere mich noch mit Schaudern an das UCSD-Pascal Konzept, den Benutzer von allem abzuschotten, was im entferntesten mit hardwarenaher Programmierung zu tun hatte. ALICE Pascal erlaubt den Zugriff auf alle GEMDOS, BIOS und XBIOS Routinen. Ja sogar der Interpreter selbst legt seine Arbeitsdaten bei Bedarf bereitwillig auf den Tisch. Damit haben Tüftler alle Trümpfe in der Hand, Geniales zu zaubern. Als kleines Beispiel finden Sie in allen Benchmark Programmen den Zugriff auf die GEM-DOS-Routinen Tsettime() und Tgetti-me() in den Prozeduren settime und gettime, die für die Zeitmessung herangezogen wurden. Ansonsten unterstützt ALICE den ISO-Pascal Standard.
Obwohl ALICE eindeutig auf Anfänger ausgerichtet ist, ist es interessant, etwas über die Leistungsfähigkeit des Interpreters zu erfahren. Schließlich möchte man auch als Anfänger nicht unbedingt im Kopf schneller rechnen als der Computer. Direkter Konkurrent für ALICE ist natürlich das ST-BASIC, welches mit dem Computer ausgeliefert wird. Könner schätzen auf dem ST ja im allgemeinen C. Deshalb ist es vielleicht interessant zu sehen, wie ALICE im Vergleich zur „Muttersprache“ des ST abschneidet. Ich habe den MEGAMAX Compiler zum Vergleich herangezdgen. Die Benchmark Programme wurden [1] entnommen und für ALICE angepaßt. Listing 1-5 zeigen die ALICE-Programmlistings. Es handelt sich im einzelnen um folgende Programme:
program fibonacci(input, output);
{$I zeit.pas}
{Berechnung der Fibonacci Zahlen}
const
ntimes = 1;
number = 20;
var
i, wert, hr, min, sec : integer;
function fib(x: integer) : integer;
{Rekursive Berechnung der Fibonacci Zahl}
{+ Declarations]
begin
if x > 2 then begin
fib := fib(x - 1) + fib(x - 2);
end
else begin
fib := 1;
end;
end;
begin
ClrScr;
writeln{'Fibonacci Zahlen');
writeln ;
writeln(ntimes:3, ' Iterationen.');
settime(0, 0, 0);
for i := 1 to ntimes do begin
wert := fib(number);
end;
gettime(hr, min, sec);
writeln(hr:2, ':', min:2, ':', sec:2);
writeln('Fibonacci(', number:2, ') = ', wert:10);
end.
Listing 1: Berechnung der Fibonacci Zahlen
FIBONACCI
Dieses Programm berechnet eine Zahl aus der Fibonacci Folge. Diese ist rekursiv definiert nach der Regel an = an-i + an-2, wenn n>2 ist, a1 = a2=1. Damit wird also das Rekursionsverhalten des Interpreters/Compilers getestet. Dieses Programm läuft natürlich nicht in ST-BASIC.
FLOAT
Mit diesem Programm werden die Gleitkommaroutinen für Multiplikation und Division getestet.
ERATO
Das Sieb des Eratosthenes. Findet Primzahlen nach der o.g. Methode. Testet die Schleifen- und Feldroutinen. Benutzt nur Integerarithmetik.
QUICK
Rekursives Quicksort Programm. Sortiert ein zufällig erzeugtes ganzzahliges Feld der Größe nach. Testet Rekursionsverhalten und Entscheidungen. Läuft wegen der Rekursion nicht in ST-BASIC.
SAVAGE
Dies ist der gemeinste Test. Er liefert Aussagen über die Schnelligkeit und Genauigkeit der transzendenten Funktionen und der Wurzelfunktion. Da in der Zuweisung immer eine Funktion und ihre Umkehrfunktion gepaart Vorkommen, muß der Wert am Schluß genau so groß sein wie die Zählvariable. Die Abweichung sagt etwas über die Genauigkeit der entsprechenden Routinen aus.
Die Ausführungszeiten sind in Tabelle 1 zusammengefaßt. Abb.4 zeigt noch einmal die Ergebnisse graphisch dargestellt. Es zeigt sich, daß ALICE von der Geschwindigkeit her dicht bei den entsprechenden BASIC Programmen liegt. Es sind halt beides Interpreter. Die Ausführungszeiten entsprechen im allgemeinen den Erwartungen. Natürlich fegen die -Compiler ab wie die Feuerwehr. Lediglich das Ergebnis für den Savage-Test überrascht. ST-BASIC am schnellsten? Liegt vielleicht an der Genauigkeit? Tabelle 2 macht das Erstaunen perfekt: Der Geschwindigkeitsunterschied zwischen BASIC und ALICE läßt sich zwar erwartungsgemäß auf den Genauigkeitsunterschied zurückführen, bleibt aber die bittere Erkenntnis, daß der MEGAMAX Compiler im Bereich der transzendenten Funktion offensichtlich Schwächen aufweist.
Tabelle 2: Abweichung des berechneten Wertes vom erwarteten Wert 5000 im Programm SAVAGE.
ST-BASIC: -3547.94
ALICE: -9.304E-7
PascalPlus: -9.147
MEGAMAX C: -2276.545
program float(input, output);
{$I zeit.pas}
{Test der Real-Arithmetik}
const
const1 = 3.141597E0;
const2 = 1.7839032E4;
count = 10000;
var
i, hr, min, sec : integer;
a, b, c : real;
begin
ClrScr ;
writeln('Floating Test');
writeln ;
settime(0, 0, 0);
a := const1;
b := const2;
for i := 1 to count do begin
c := a*b;
c := c/a;
c := a*b;
c := c/a;
c := a*b;
c := c/a;
c := a*b;
c := c/a;
c := a*b;
c := c/a;
c ;= a*b;
c := c/a;
c := a*b;
c := c/a;
end;
gettime(hr, min, sec);
writeln(hr:2, ':', min:2, ':', sec:2);
end.
Listing 2: Float Test
Da MEGAMAX die Möglichkeit bietet, unter hinzulinken der Datei DOUBLE.L die Routinen mit doppelter Genauigkeit zu benutzen, habe ich natürlich von dieser Möglichkeit Gebrauch gemacht. In der Tat hat MEGAMAX dann eine vergleichbare Genauigkeit (-7E-6), aber die Ausführungszeit ist auf 990 sec angewachsen! Offensichtlich besitzt ALICE ganz ordentliche Routinen für Gleitkommaarithmetik.
So vorteilhaft sich Interpreter bei der Bedienung auch darstellen, sowohl mit der Geschwindigkeit als auch mit der Weitergabe eigener Programme, gibt es Schwierigkeiten. Wie wir oben gesehen haben, sticht das Geschwindigkeitsproblem bei ALICE nicht so sehr. Wohl aber die Möglichkeit, eigene Programme weiterzugeben. ALICE ermöglicht zwar, Programme sowohl im komprimierten *.AP Format als auch als Textfiles abzuspeichern, aber damit kann der Benutzer lediglich den Source Code seines Programms weitergeben. Dies hat den Nachteil, daß der Empfänger des Programms im Besitz eines Interpreter oder Compilers der gleichen Sprache sein muß, wenn er das Programm benutzen will. Weiterhin gibt der Autor mit dem Programm seinen mühsam erarbeiteten Quellcode frei, was natürlich zum „Lernen“ anregt. Das erste Problem ist durch sogenannte Run-Only Interpreter gelöst. Im Gegensatz zu GFA, die für ihren BASIC-Interpreter gleich eine Run-Only-Interpreter Version zum Vertrieb freigeben, konnte sich Looking Glass Software zu dieser Freizügigkeit (noch) nicht entschließen. Ernsthaft Interessierte sollten deshalb den Run-Only-Interpreter APRUN.PRG gleich mitbestellen, um Freunden oder der PD den Genuß selbstgeschriebener AP-Programme zu ermöglichen. Offensichtlich hat man aber von vornherein eine andere Strategie ins Auge gefaßt. Da auch die Autoren von ALICE um die Geschwindigkeit von Interpretern wissen, haben sie im Filemenü den Menüpunkt Invoke Compiler mit aufgenommen, der automatisch das aktive Programm als Text abspeichert, den PASCAL Compiler aufruft und anschließend zu ALICE zurückkehrt. Im Handbuch und im AP.INI File sind die Daten für den OSS-Compiler aufgeführt. Trotzdem dürften hier Probleme auftauchen, weil der Zugriff auf das GEM bei ALICE eben doch etwas anders abläuft als bei den PASCAL Compilern für den ST. Diese Option ist wohl eher für den IBM-PC und Turbo-Pascal gedacht gewesen.
program SieveOfErastothenes(input, output);
{$I zeit.pas}
{ Calculates prime numbers up to 2 * size + 3 }
const
size = 1000;
var
hr, min, sec : integer;
i, prime, k, count, iter : integer;
flags : array [0..size] of Boolean;
begin
settime(0, 0, 0);
count := 0;
{ Initialize the array of flags }
{ Start off with all numbers being prime }
for i := 0 to size do begin
flags[i] := true;
end;
for i := 0 to size do begin
{ Cross non-primes off the list }
{ Found a number that hasn't been crossed }
{ off, so it must be prime }
if flags[i] then begin
prime := i + i + 3;
{ Print out the prime }
{
writeln(prime);
}
k := i + prime;
{ Cross out all the multiples of this }
{ prime }
while k < size do begin
flags[k] := false;
k := k + prime;
end;
count := count + 1;
end;
end;
gettime(hr, min, sec);
writeln(hr:2, ':', min:2, ':', sec:2);
writeln(count, " primes") ;
{ Write the final number of primes }
end.
Listing 3: Das berüchtigte Sieb des Erastothenes
ALICE Pascal ist ein leistungsfähiger PASCAL Interpreter. Turbo Pascal Programme sind mit minimalen Änderungen lauffähig. Der an der PASCAL Syntax orientierte Editor verhindert weitestgehend Syntaxfehler bereits beim Eintippen des Programmtextes und stellt damit die ideale Lernhilfe für PASCAL-Anfänger dar. Alle Fehlermeldungen werden reichlich (um nicht zu sagen schwatzhaft) kommentiert (leider in Englisch). Zugriff auf GEM ist möglich und z. Teil für Anfänger erheblich vereinfacht. Wer interessiert ist, PASCAL zu lernen, sollte ALICE in Betracht ziehen. Als Könner sollte man allerdings die Kosten eines guten PASCAL Compilers gleich mit einkalkulieren. Oder man erweitert seinen Horizont und betrachtet PASCAL als Sprungbrett für C und kauft sich einen C-Compiler.
Dr. Sarnow
Produkt
ALICE. The Personal PASCAL.
Hersteller
Looking Glass Software Limited
4 King St. N.
terloo, ON
N2J 2X8
Canada
Literatur
[1] BYTE, July 1987, Vol.12, No. 8, p. 101 ff.
Preis: 79,95 $ (US) + 15 S Fracht
program quicksort(input, output);
{$I zeit.pas}
{Sortiert ein Array mit real-Zufallszahlen}
const
maxnum = 100;
count = 10;
type
feld = array [1..maxnum] of integer;
var
i, j, temp, hr, min, sec : integer;
buffer : feld;
procedure quick(lo, hi: integer; var base: feld);
{Rekursiver Quicksort}
var
i, j, k, pivot, temp : integer;
begin
if lo < hi then begin
j := hi - 1;
pivot := base[hi];
i := lo;
while i < j do begin
while (i < hi) and (base[i] <= pivot) do begin
i := i + 1;
end;
while (j > lo) and (base[j] >= pivot) do begin
j := j - 1;
end;
if i < j then begin
temp := base[i];
base[i] := base[j];
base[j] := temp;
end;
end;
if base[i] >= base[hi] then begin
temp := base[i];
base[i] := base [hi];
base[hi] := temp;
quick(lo, i - 1, base);
quick(i + 1, hi, base);
end;
end;
end;
begin
ClrScr ;
writeln('Quicksort');
writeln ;
settime(0, 0, 0);
for i := 1 to count do begin
for j := 1 to maxnum do begin
buffer[j] := round(10000*random);
end;
writeln('Buffer voll, Iteration ', i);
quick(1, maxnum, buffer);
end;
gettime(hr, min, sec);
writeln(hr:2, ':', min:2, ':', sec:2);
end.
Listing 4: Schnell Sortiert - Der Quicksort
program savage(input, output);
{$1 zeit.pas}
{Test der arithmetischen Genauigkeit)
const
iloop = 5000;
var
i, hr, min, sec : integer;
wert : real;
function tan(x: real) : real;
{Berechnet den Tangens eines reellen Wertes }
begin
tan := sin(x)/cos(x);
end;
begin
ClrScr ;
writeln('Savage Benchmark');
settime(0, 0, 0);
wert := 1.0;
for i := 1 to iloop do begin
wert := tan(arctan(exp(ln(sqrt(wert*wert))))) + 1.0;
end;
gettime(hr, min, sec);
writeln(hr:2, ':', min:2, ':', sec:2);
writeln('Abweichung=', wert - iloop - 1);
end.
Listing 5: Savage: der Genauigkeitstest - hier fallen die Hüllen
const
gemdos = 62;
tgettime = 44;
tsettime = 45;
procedure settime(hr, min, sec: integer);
{Setzt die Uhr}
var
zeit : integer;
begin
zeit := sec and 63;
zeit := zeit + ((min shl 6) and 4032);
zeit := zeit + ((hr shl 12) and $1F000);
CProc(gemdos, tsettime, zeit);
end;
procedure gettime(var hr, min, sec: integer);
{Gibt die Systemzeit zurueck}
var
zeit : integer;
begin
zeit := 2*CIntFunc(gemdos, tgettime);
sec := zeit and 63;
min := (zeit and 4032) shr 6;
hr := (zeit and $1F000) shr 12;
end;
Listing 6