Tips und Tricks für C-Programmierer

Portable Registeroptimierung in C

In der Sprache C legt der Programmierer durch den Typendeklarations-Zusatz »register« die lokalen Variablen in den Prozessorregistern fest. Leider treten dabei häufig Probleme bei der Portierung auf einen anderen Compiler bzw. Computer auf, weil die Anzahl der freien Register für Variablen nirgends vorgeschrieben ist. Oft muß der Programmierer einige Registervariablen-Deklarationen per Hand entfernen, weil der neue Compiler weniger Register zur Verfügung stellt. Eine weitaus komfortablere Lösung liegt darin, genügend Makros der folgenden Kategorie zu definieren:

    #define DREG_0 register /* Datenreg. */
    #define DREG_1 register /* Datenreg. */
    #define AREG_0 register /* Adressreg. */

Statt »register« versehen Sie Ihre Variablen mit diesen Makros. Die wichtigste Variable erhält »DREG_0«, die nächste »DREG_1 « usw. Das gleiche gilt tür die Adreßregister, denen gewöhnlich Datenzeiger zugeordnet sind. Ein Beispiel einer angepaßten Funktion sieht so aus:

    void function(void)
    AREG_0 char *rptr;
    DREG_0 int n;
    DREG_1 long l;

Stellen Sie nun bei der Portierung fest, daß weniger Register zur Verfügung stehen, so entfernen Sie lediglich ab den zu hohen Registernummern das Wort »register« aus den Makros.
(Martin Backschat/ah)

    #define DREG_0 register
    #define DREG_1 register
    #define DREG_2  /* nur 2 Datenreg. da */

Cursortasten über Joystick simulieren

Mit Hilfe der nachfolgend aufgeführten »joycursor«-Funktion in Turbo C können Sie einen in den Mausport gesteckten Joystick verwenden, um die Cursortasten (zum Beispiel in einer TOS-Anwendung) zu ersetzen. Dabei müssen Sie allerdings auf die Maus verzichten. Übergeben Sie zunächst die drei Parameter r, t und v. Diese geben Zeiten in 1/10tel Sekunden an, die die Reaktion des Cursors auf Joystickbewegungen beeinflussen. Mit dem Parameter r legen wir den Zeitraum fest, in dem der Parameter t die Wiederholgeschwindigkeit der Cursorbewegungen bestimmt. Nach dem Zeitraum r verwenden wir die Wiederholgeschwindigkeit v. Wünschen wir also beispielsweise in den ersten zwei Sekunden eine Zeit von 0,5 Sekunden zwischen zwei Cursorbewegungen und darauf eine Zeit von 0,2 Sekunden, so setzen wir r auf 20, t auf 5 und v auf 2.

    joycursor (20, 5, 2);   /* Joystick als Ersatz für Cursorblock */

Die »joycursor()«-Funktion macht sich den Tastaturprozessor-Befehl mit dem Hexadezimalcode 09 zunutze, der den Cursortasten-Simulationsmodus aktiviert. Neben dem Befehl senden wir sechs weitere Bytes an den Tastaturprozessor, um die Tastenwiederholungszeiten anzugeben. Diese können in horizontaler und vertikaler Richtung unterschiedlich sein. Unsere Funktion verwendet für beide Richtungen die gleichen Werte. Mit Hilfe der »Ikbdws()«-XBIOS-Funktion (#include <tos.h> nicht vergessen) senden wir die Bytefolge an den Tastaturprozessor. Dazu übergeben wir deren Länge und Adresse.
(Frank Mathy/ah)

        void joycursor (unsigned char r, unsigned char t, unsigned char v)
        {
            unsigned char joycur[7];
            joycur[0] = 0x09;   /* Befehlswort */
            joycur[1] = joycur[2] = r;
            joycur[3] = joycur[4] = t;
            joycur[5] = joycur[6] = v;
            Ikbdws (7, joycur); /* Joystick als Cursortast. */
        }

Blitter ein- und ausschalten

Ab TOS 1.2 unterstützt das ST-Betriebssystem den Blitterchip, der die Bildschirmausgabe beschleunigt. Mit Hilfe der»Blitmode()«-Funktion der XBIOS-Bibliothek des TOS können Sie auch unter Turbo C den Blitter ein- und ausschalten bzw. seinen aktuellen Zustand bestimmen. Vor deren Anwendung ist die Datei »tos.h« in den Quelltext zuzuladen. Die Funktion erwartet einen Parameter vom Typ Integer, der die gewünschte Aktion festlegt. Mit dem Wert -1 fragen wir den Zustand ab, Null bewirkt das Ausschalten bzw. eine Eins das Einschalten des Grafik-Beschleunigers. In jedem Fall erhalten wir nach dem Funktionsaufruf den Zustand des Blitters als Integer-Ergebnis zurück.
(Frank Mathy/ah)

    int aktiv;
    aktiv = Blitmode(-1);   /* Zustand testen */
    if (aktiv == 1)
        puts ("Blitter an");
    else
        puts ("Blitter aus") ;
    aktiv = Blitmode (1);   /* Blitter einschalten */
    aktiv = Blitmode (0);   /* Blitter ausschalten */

Angeschlossene Laufwerke ermitteln

Für verschiedene Applikationen ist es wichtig, die vorhandenen logischen Disketten- oder Festplattenlaufwerke zu kennen. Die Funktion »Drvmap« liefert hierzu ein Langwort zurück, dessen Bits 0 bis 15 die Laufwerke A bis P repräsentieren. Ist ein Bit gesetzt, ist das zugehörige Laufwerk vorhanden. Für das Laufwerk C wäre folgender Test nötig:

    long drives;
    drives = Drvmap();  /*Laufwerke ermitteln */
    if (drives & 4)
        puts ("Laufwerk C vorhanden");
    else
        puts ("Laufwerk C nicht vorhanden");

Die folgende Funktion testet, ob das angegebene Laufwerk vorhanden ist. Wir übergeben hierzu die Laufwerksnummer (0 bis 15 für die Laufwerke A bis P) und erhalten den Wert Eins zurück, wenn das Laufwerk angeschlossen ist, ansonsten Null.
(Frank Mathy/ah)

    int testdrive (int nummer)  /* Test, ob Laufwerk vorhanden*/
    {
        long drives, bit;
        drives = Drvmap (); /* Laufwerke ermitteln */
        bit = 1 << nummer;  /* Laufwerksbit setzen */
        return ((drives & bit) == bit); /* Testen */
    }

Laufwerkskapazität ermitteln

Informationen zum Aufbau und freien Speicherplatz eines Laufwerks gibt die Funktion »Dfree()« der TOS-Bibliothek. Hierfür deklarieren wir zunächst eine »DSPACE«-Variable, die eine Struktur mehrerer »unsigned Long«-Elemente darstellt. Die Funktion erwartet neben der Adresse der »DSPACE«-Variablen die Nummer des Laufwerks.

    DSPACE platz;   /* Variable für Informationen */
    Dfree (&platz,2);   /* Hole Info für Laufwerk C: */

Das Element »platz.bps« gibt die Anzahl der Bytes pro Sektor an. Die Anzahl der Sektoren pro Cluster enthält das Element »platz.pspal«. Die Anzahl der insgesamt verfügbaren Cluster auf dem Datenmedium entnehmen wir der Variablen »platz.total«, die Zahl der freien Cluster steht in »platz.freal«.

(Frank Mathy/ah)

unsigned long frei, total; printf ("%lu Bytes pro Sektor\n", platz.bps); printf ("%lu Sektoren pro Cluster\n", platz.pspal); frei = platz.freal * platz.pspal * platz.bps; total = platz.total * platz.pspal * platz.bps; printf ("%lu von %lu Bytes frei\n", frei, total); # Unterstützung durch den Coprozessor

Eine Stärke von Turbo C ist die serienmäßige Unterstützung des MC68881-Mathematik-Coprozessors. Mit Hilfe der »fpumode()«-Funktion der Mathematik-bibliothek (#include <math.h>) testen Sie, ob der flinke Mathematik-Experte vorhanden ist. Hierzu übergeben Sie der Funktion den Wert Null. Als Ergebnis liefert die Funktion den Wert Null (FPU vorhanden) oder den Wert Eins (FPU nicht vorhanden).

    if (fpumode(0) == 1)
        puts ("MC68881 vorhanden");
    else
        puts("Kein MC68881 vorhanden");

Ist der Coprozessor vorhanden, bedient sich Turbo C von Anfang an seiner Hilfe. Wollen Sie auf diese Unterstützung verzichten, deaktivieren Sie den MC68881 über die »fpumode()«-Funktion. Hierzu übergeben Sie den Wert Eins. (Frank Mathy/ah)

    test = fpumode (1); /* MC68881 aus */

Hinweis: Es wird nur die Coprozessorkarte für den Mega ST von Atari unterstützt. Der Coprozessor im TT wird erst von Pure C unterstützt!


Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]