Capslock-Anzeige mit 16 Pixeln

Programmierer haben viel am ST und dessen ROMs zu kritisieren - Anwender werden sich wahrscheinlich schon darüber geärgert haben, dass die Shift-Verriegelung, also CapsLock, nicht durch eine Leuchtdiode an der Tastatur vermerkt wird. Wir nehmen sechzehn Pixel des Bildschirms, etwas TURBO-C und schaffen so Ersatz.

Bild 1: Die fehlende LED wird durch 16 Pixel ersetzt.

Wählt man bei der Eingabe eines Textes durch Drücken der Taste CapsLock, werden alle Eingaben automatisch in Großbuchstaben gewandelt. Leider erhält man kein Feedback durch eine LED-Anzeige und weiß nach einiger Zeit vielleicht nicht mehr, ob die Shift-Verriegelung eingeschaltet ist oder nicht. Während bei PC-Tastaturen eine Leuchtdiode für wenige Pfennige dies anzeigt, muß man beim ST im Kopf behalten, ob Großschreibung gewählt ist.

Abhilfe schafft das Programm CAPSLOCK, das am besten in den AUTO-Ordner kopiert wird und dann durch ein kleines Kästchen am rechten oberen Bildschirmrand signalisiert, ob CapsLock momentan gültig ist. Mit den dabei verwendeten sechzehn Pixeln für eine 4*4-Anzeige ersetzen wir die LED, die Atari aus unerfindlichen Gründen nicht einbauen mag. Für Programmierer ist interessant, daß hier eine schnelle VBL-Routine implementiert wird, ohne auf einen Assembler zurückzugreifen.

Installation für Anwender

Listing 1 zeigt das kurze Programm, das mit TURBO-C 2.0 übersetzt werden muß. Die Projektdatei in Listing 2 setzt verschiedene Compiler-Optionen und erzeugt ein entsprechendes Programm. Das Compilat sollte direkt in den AUTO-Ordner kopiert werden, wobei die Reihenfolge der AUTO-Programme egal ist.

Nach dem nächsten Booten erscheint rechts oben am Bildschirmrand ein kleines Kästchen. Ist seine Mitte weiß, ist CapsLock nicht eingestellt, und alle Eingaben werden direkt übernommen. Ein ausgefülltes Kästchen signalisiert, daß CapsLock gedrückt wurde und alle Tastendrücke in Großbuchstaben gewandelt werden. Das Programm ist auf normale GEM-Programme ausgelegt, so daß diese Darstellung schwarz auf weiß in der Menüzeile erfolgt. Sollten Sie Programme benutzen, bei denen der Bildschirmhintergrund schwarz ist, zeigt ein kleiner weißer Punkt an. daß CapsLock nicht gewählt ist; seine Abwesenheit signalisiert Großschreibung. Bild 1 stellt diese Anzeigen nochmals dar.

Natürlich kann die Anzeige bei einigen Programmen stören. Bei GEM-Programmen ist aber fast immer der äußerst rechte Rand der Menüzeile unbenutzt. Bei TOS-Programmen überschreibt die Anzeige wegen ihres geringen Ausmaßes keine ganzen Zeichen. Zudem ist die Ecke rechts oben immer ein potentieller Kandidat zum Weg-Scrollen, so daß das Überschreiben der sechzehn Pixel letztendlich doch nicht stört.

Kleine Programmübersicht

CAPSLOCK installiert eine kleine VBL-Routine, die besagte sechzehn Pixel überschreibt. Dabei entscheidet die Systemvariable kbshift darüber. ob das Kästchen gefüllt oder leer dargestellt wird. In der Initialisierung in main() stellt das Programm nach einer Meldung zunächst in l[0] die Speicheradresse des Bytes fest, das die letzten Pixel der zweiten Bildschirmlinie enthält.

Mit Hilfe von LineA-Variablen werden dann in l[1] bis l[3] die Adressen des Bildschirmspeichers für die darunterliegenden drei Bildschirmzeilen ermittelt. Da nach dem Aufkommen von Bildschirmerweiterungen wie OverScan und STE sowie TT sich diese Adresse nicht aus den Bildschirmausmaßen errechnen läßt, ist die Verwendung der Anzahl der Speicher-Bytes pro Bildschirmzeile nötig.

Die Adresse der Systemvariablen kbshift ist ab dem Blitter-TOS im System-Header vermerkt. Im Supervisor-Modus wird diese Adresse ausgelesen und im Zeiger kbshift vermerkt.

Nun soll eine VBL-Routine installiert werden. Dazu ermittelt CAPSLOCK aus der Systemvariablen _vblqueue die Adresse des „nullten“ VBL-Slots. Da dieser aber vom GEM benutzt wird, muß ab dem nächsten Slot auf einen freien Zeiger - d.H. auf einen NULL-Zeiger - gesucht werden, was die kleine for-Schleife erledigt.

Nun steht in i die Nummer der VBL-Slots. Ist dieser Wert größer der Anzahl verfügbarer VBL-Einträge, bricht CAPSLOCK mit einer Fehlermeldung ab. Andernfalls wird in den VBL-Slot, auf den vbl zeigt, die Routine capsvbl eingetragen und das Programm resident im Speicher verankert. Nun wird siebzig Mal pro Sekunde capsvbl aufgerufen. Ob noch Platz für eine VBL-Routine war, entscheidet über die ausgegebene Mitteilung und über das Ergebnis des Programms. In jedem Fall wird der Prozessor aber wieder in den User-Modus geschaltet.

capsvbl ist nun sehr einfach zu formulieren. Wenn Caps-Lock gilt, soll ein ausgefülltes Kästchen in den Bildschirm geschrieben werden, ansonsten ein leeres. Der obere und untere Rand des Kästchens läßt sich einfach durch Odem des Bildschirminhalts mit einem vier Pixel breiten Strich erledigen -die Adressen liegen in l[0] und l[3] vor.

Für die zwei Bildschirmzeilen dazwischen entscheidet Bit 4 in kbshift - genau dann ist CapsLock gewählt - über den Bildschirminhalt. Ist das Bit gesetzt, wird ein ausgefülltes Muster geodert. ansonsten schreibt CAPSLOCK nur die Ränder. Damit der Wechsel von Rahmen nach Ausgefüllt möglich ist, muß der Bildschirm vorher mit einem AND über die Kästchenbreite ausmaskiert werden.

Die Muster on und off sind als Makros definiert. Wir wählen in der vorliegenden Form einen ein Pixel breiten Rand und stellen ein Kästchen dar. Mit einer kleinen Modifikation ließe sich auch ein kleiner Kreis anzeigen.

Nachdem die VBL-Routine bei jedem Bildschirmaufbau angesprochen wird - das ist beim SM 124 siebzig Mal pro Sekunde - stellt sich natürlich die Frage, ob eine Formulierung dieser Routine in der Hochsprache - das wird ab und an angezweifelt - C schnell genug ist. Ein Blick in das Disassembling wird auch den Assembler-Freak zufriedenstellen - der TURBO-C-Compiler liefert hier einen wirklich annehmbaren Code. Die Sicherung der Geschwindigkeit wird allerdings dadurch gewährleistet, daß alle nötigen Berechnungen schon bei der Initialisierung durchgeführt werden.

Einschränkungen

Wenn alle nötigen Kalkulationen bei der Initialisierung stattfinden, heißt das allerdings auch, daß nicht mehr auf Veränderungen beispielsweise der Bildschirmauflösung reagiert werden kann. So verschwindet die Anzeige z.B.. wenn unter Overscan die Auflösung heruntergeschaltet wird, da der Bildschirm dann einen völlig anderen Speicherbereich darstellt.

Weiterhin ist unsere Methode des direkten Schreibens in den Bildschirmspeicher mit Bit-logischen Operationen auf die monochrome Darstellung beschränkt. CapsLock ist aber insbesondere bei Textverarbeitung von Bedeutung - und Textverarbeitung findet auf dem ST meistens in weißschwarz statt.

/*
CAPSLOCK - CapsLock-Anzeige

by Robert Tolksdorf     (c) 1991 MAXON Computer

*/

#include <tos.h>
#include <linea.h>

char    *kbshift,   /* Zeiger a. kb_shift */
        *l[4];      /* Zeiger a. Bildschirmspeicher */

/* Die Bitmuster für das Kästchen */

#define on  30      /* ---XXXX- */
#define off 18      /* ---X--X- */

/* Die VBL-Routine */ 
void capsvbl()
{
*l[0] = *l[0] | on;
*l[1] = (*l[1] & (255-on)) | ((*kbshift & 16) ? on : off);
*l[2] = (*l[2] & (255-on)) | ((*kbshift & 16) ? on : off);
*l[3] = *l[3] | on;
}

main()
{
SYSHDR  *SysHead; 
long    Superstack; 
long    *vbl; 
int     i;
char    *mess[3]= { "\x1Bp CAPSLOCK-Display V 1.0 \x1Bq\r\n" \
                    " by Robert Tolksdorf\r\n"\
                    " (c) 1991 MAXON Computer\r\n", 
                    "Installed\r\n\n",
                    "Not installed (no free VBL-Slot)\r\n\n"};

/* erstmal melden */
Cconws(mess[0]);
/* Bildschirmadressen rechts oben ermitteln */
linea_init();
l[0]=Logbase();
l[0]=l[0]+(long)(Vdiesc->v_rez_hz/8)-1+(long)Vdiesc->bytes_lin; 
for (i=1; i<=3; i++)
    l[i] =l[i-1]+(long)Vdiesc->bytes_lin;
/* Adresse von kb_shift auslesen */ 
SuperStack=Super(0L);
SysHead=*(long *)0x4F2L; 
kbshift=SysHead->kbshift;
/* VBL installieren, also NULL-Zeiger suchen */ 
i=1;
for (vbl=*(long *)0x456L, vbl++;
    (i<(int)0x454L) && (*vbl!=0L);
        (long)vbl++, i++);
/* War ein Slot frei ? */ 
if (i<(int)0x454L)
{
    /* VBL installieren */
    *vbl=capsvbl;
    Super((void *)SuperStack);
    Cconws(mess[1]); /* Installed */
    /* und resident bleiben */
    Ptermres(_PgmSize,0);
}
else
{
    Super((void *)SuperStack);
    /* Fehlermeldung */
    Cconws(mess[2]); /* Not installed */
    /* terminieren */ 
    return(1);
}
}
; CAPSLOCK.PRJ zum autom. Erstellen von CAPSLOCK 

CAPSLOCK.PRG
.C[-W-sus -W-apt]   ; wir machen uns bei Zeigern verdächtig
.L[-S=512]          ; und brauchen kaum Stack-Platz
=

TCSTART.O           ; der Startup-Code (könnte man kürzen) 
CAPSLOCK.C          ; main, vbl-Routine 
TCSTDLIB.LIB        ; TC-Standard-Library
TCTOSLIB.LIB        ; TOS library
TCLNALIB.LIB        ; Line-A-Library


Robert Tolksdorf
Links

Copyright-Bestimmungen: siehe Über diese Seite