                         TURBO Pascal 3.0 Projekte

    -------------------------------------------------------------------

    1. Problematik der Hintergrundverarbeitung von Tastatureingaben
    (CP/M)

    Bekanntlich ist CP/M ein System, bei dem dem Programmierer keine
    Mglichkeit der Interruptprogrammierung zur Verfgung steht. Es
    sei denn, man pat sich speziell an die Hardware seiner Maschine
    an, wobei allerdings das Betriebssystem umgangen wird. Dies hat
    den Nachteil, da unter dieser Voraussetzung entwickelte Programme
    eben nur an einer einzigen Maschine lauffhig sind, was dem
    eigentlichen Sinn von CP/M entgegen spricht.

    Eine Mglichkeit bietet sich dem Assemblerprogrammierer, der an
    geeigneter Stelle eine Abfrage der Tastatur einbauen kann, z.B.
    immer dann, wenn rechenintensive Operationen durchgefhrt werden.
    Ein anschauliches Beispiel fr eine solche Anwendung bietet der
    Editor VDO25, der aus dem Public Domain Bereich erhltlich ist.

    Jedoch auch dem TURBO PASCAL Programmierer bietet sich eine
    Mglichkeit, den Zustand der Tastatur abzufragen und anstehende
    Zeichen zu sammeln, bis diese bei einer Eingabe bentigt werden.
    Eine Mglichkeit ist, eine Prozedur zu schreiben, die dann zum
    geeigneten Zeitpunkt aufgerufen wird, hnlich der erwhnten
    Methode der Assemblerprogrammierung. Schner wre es jedoch, wenn
    der Aufruf einer solchen Prozedur automatisch erfolgt. Mit einem
    kleinen Trick lt sich eine bestimmte Eigenschaft von TURBO
    PASCAL (hier wird Bezug genommen auf die Version 3.0) fr diese
    Zwecke ausnutzen.

    Dem Handbuch ist zu entnehmen, da mit dem Compilerbefehl {$U+}
    eine Abfrage der Tastatur erfolgt speziell fr das Kontrollzeichen
    Ctrl-C, was als Unterbrechung interpretiert wird.

    Was verbirgt sich nun hinter dieser Option bezogen auf die
    Ausfhrung des Prozessors Z80 (oder 8080)?
    Der Compiler fgt schlicht hinter jede Anweisung den
    Operationscode RST 38H (Z80 Mnemonic) bzw. RST 7 (8080 Mnemonic) -
    Hex Code FF. Diese Anweisung wirkt exakt wie ein
    Unterprogrammaufruf (CALL), d.h. der Program Counter wird auf dem
    Stack abgelegt und - in diesem Falle - ein Aufruf der Adresse
    Hex 0038 ausgefhrt. In dieser Adresse steht i.a. ein Sprung auf
    eine Adresse, wo die eigentliche Routine ausgefhrt wird. Auf den
    ersten Blick sieht diese Aktion etwas umstndlich aus, der Vorteil
    gegenber einem direkten CALL liegt in der Krze der Anweisung.
    Ein CALL bentigt drei Bytes, die RST Anweisung jedoch nur ein
    Byte.
    (Die RST Mglichkeit war brigens bei den lteren Prozessoren 8080
    die gngige Art, Interrupts zu bearbeiten).
    Und hier gibt es nun Schwierigkeiten mit dem JOYCE, weil bei
    dieser Maschine die Interrupts ber die RST 7 Anweisung ausgefhrt
    werden, also ein Konflikt besteht zwischen JOYCE Interrupts und
    TURBO PASCAL Option {$U+}.
    In der Tat wird jeder JOYCE Benutzer, der diese Option zur
    gezielten Programmunterbrechung bereits eingesetzt hat, bse
    berraschungen erlebt haben, am JOYCE funktioniert diese Option
    nmlich nicht (Wobei sich diese Aussage allerdings auf TURBO
    Versionen bezieht, die etwa Anfang bis Mitte 1986 angeschafft
    wurden. Ob dieser Misstand mittlerweile abgebaut ist, kann ich
    nicht sagen).
    Glcklicerweise zeigt sich der Vertreiber von TURBO PASCAL, die
    Firma HEIMSOETH Software auf Fragen sehr zuvorkommend. Es sei
    deshalb hier die ntige nderung der Datei TURBO.COM angegeben,
    die den ursprnglichen RST 7 auf RST 6 (Hex F7) ndert. Dadurch
    funktioniert die Compiler Option {$U+} einwandfrei.

    2. TURBO PASCAL 3.0 Patch

    Bentigt werden dazu die Dateien TURBO.COM und SID.COM auf
    mglichst gleicher Diskette. Dann mssen folgende Kommandos
    eingetippt werden:


        A>SID TURBO.COM          ( Aufruf des Debuggers             )
        CP/M 3 SID - Version 3.0 ( Bereitmeldung von SID            )
        NEXT MSZE  PC  END
        7980 7980 0100 D2FF      ( Statistikausgabe von SID         )
        #F372,F372,30            ( Umsetzen RST 7 auf RST 6         )
        #F378,F378,31            (          dto.                    )
        #F595,F595,F7            ( OpCode ndern                    )
        #WTURBOP.COM             ( Neue Datei TURBOP.COM erzeugen   )
        00F1h record(s) written  ( SID Fertigmeldung                )
        #^C                      ( STOP Taste am JOYCE              )
        A>TURBOP                 ( Aufruf des genderten Compilers  )

    3. Die TURBO PASCAL Routinen

    Vorgestellt wird hier nun eine Reihe von Prozeduren und
    Funktionen, die als Include Datei vorliegen, um die Compiler
    Option {$U+} zum Sammeln von Zeichen auszunutzen.

    Vorab sei auf folgende Nachteile hingewiesen:

      1. Die Option {$U+} erhht die Ausfhrungszeit von Programmen
      2. Ein Sammeln von Zeichen ist nur sinnvoll bei der Verarbeitung
         von Strings. Das Verarbeiten von Zeichen ist mglich, ebenso
         von Zahlen. Im letzten Fall mu allerdings eine Wandlung in
         die entsprechende Zahlentype (Integer, Real) vorgenommen
         werden.

    Die hier vorgestellten Programmteile sollen deshalb auch nur als
    Grundlage dienen.

    Damit die Prozeduren funktionieren, wird eine Typen Deklaration
    LINE bentigt, die ein String mit einer vom Programmierer
    vorgegebenen Lnge darstellt, also z.B.:

              TYPE LINE : STRING [80];

    um einen Puffer zum Sammeln von maximal 80 Zeichen
    bereitzustellen. Die Include Datei erzeugt intern vier globale
    Variable, die dann natrlich nicht mehr vom Hauptprogramm
    deklariert werden drfen. Diese sind:

       BUFFER : LINE;   Dies ist der interne Puffer fr das Sammeln
                        der Zeichen

       BUFMAX :         Dies ist eine Variable, die die maximale
       INTEGER;         Anzahl der zu sammelnden Zeichen angibt
       UOPT : BOOLEAN;  Diese Boolsche Variable zeigt an, ob eine
                        Programmunterbrechung bei Ctrl-C vorgenommen
                        werden soll oder nicht

       DETECT :         Dies ist eine interne Boolsche Variable
       BOOLEAN;

    Die Prozeduren und Funktionen:

    AHEAD;

    Diese, komplett in Assembler geschriebene Prozedur wird immer dann
    aufgerufen, wenn vom Compiler die RST 6 Funktion ausgefhrt wird.
    Falls ein Ctrl-C eingegeben wurde, so erfolgt dann ein
    Programmabbruch, wenn vorher die Variable UOPT entsprechend
    gesetzt wurde. Zu beachten ist, da zur Installation die Prozedur
    INI_AHEAD aufgerufen werden mu.

    INI_AHEAD(BUFF:INTEGER;OPT:BOOLEAN);

    Diese Prozedur installiert die besprochene Prozedur AHEAD. Sie
          setzt die Puffergrsse auf den Wert BUFF
          initialisiert den BUFFER
          trgt die Prozedur AHEAD an die RST 6 Adresse ein
     und  setzt die BREAK Option auf den Wert OPT. Ist OPT TRUE, so
          erfolgt ein Programmabbruch, wenn Ctrl-C gefunden wurde.
          (Dies wirkt wie die Originaloption {$U+})

    GET_AHEAD(VAR XIN:LINE):BOOLEAN;

    Diese Funktion, von der ein Teil in Assembler geschrieben ist,
    verarbeitet gesammelte Zeichen. Hierbei ist XIN ein Puffer, in den
    die vorhandenen Zeichen kopiert werden. Neben dem zurckgegebenen
    Boolschen Wert der Funktion wird auch noch die interne Boolsche
    Variable DETECT gesetzt. Es ergeben sich folgende Funktionen in
    Abhngigkeit der Boolschen Variablen:
     Variable:  DETECT GET_AHEAD  Funktion
     Fall 1     FALSE  FALSE      Kein Zeichen gesammelt
     Fall 2     FALSE  TRUE       Es wurden Zeichen gesammelt und
                                  komplett in den Puffer XIN
                                  bernommen. Der alte Puffer ist
                                  leer.
     Fall 3     TRUE   TRUE       Es wurden Zeichen gesammelt und ein
                                  RETURN wurde gefunden. Der neue
                                  Puffer ist bis zum RETURN gefllt
                                  und im alten Puffer sind noch
                                  Zeichen vorhanden.
    Das letzte Ergebnis erlaubt das Bearbeiten mehrerer Zeilen.

    READ_LINE(TEXT:LINE):LINE;

    Diese Funktion erlaubt das Einlesen einer Zeile aus dem Puffer.
    Als Ergebnis wird eine Zeile zurckgegeben. Bezogen auf die oben
    aufgefhrten Flle ergibt sich:
     Fall 1  Der String TEXT wird auf dem Bildschirm ausgegeben und
             eine komplette Zeile von der Tastatur eingelesen.
     Fall 2  Der String TEXT sowie die bereits gesammelten Zeichen
             werden auf dem Bildschirm ausgegeben und die Zeile von
             der Tastatur aufgefllt.
     Fall 3  Der Inhalt des Puffers wird zurckgegeben. Eine Ausgabe
             des Strings TEXT erfolgt nicht.

       * Assembler-Routine: Zeichen holen
       * Assembler-Routine: Zeichen holen (RST 6)
       * Pascal-Programm: Zeichen lesen in Type Ahead Puffer

    4. Abschliessende Hinweise

      1. Unter keinen Umstnden sollte die Option {$U+} innerhalb der
         Include Datei eingeschaltet werden. Dies kann zu
         Systemabstrzen fhren.
      2. Jedoch sollte die Option {$U+} nach der Include Datei
         eingeschaltet werden, damit der Mechanismus wirksam wird.
      3. Bei zeitkritischen Routinen kann der Mechanismus am Anfang
         einer Prozedur oder Funktion mit {$U-} abgeschaltet werden.
         Sie sollte aber am Ende mit {$U+} reaktiviert werden. Unter
         Umstnden kann dabei aber ein Zeichen verlorengehen.
      4. Im Fall 2, d.h. bei teilweise geflltem Puffer ist ein
         Lschen der bereits eingegebenen Zeichen nicht mit der
         vorliegenden Funktion READ_LINE mglich.

    -------------------------------------------------------------------

    Abgedruckt in Klubzeitung Nr. 54 - Nov. 1998.    Autor: Werner
    Cirsovius
                                                                    [Image]
