DeCenter: TT (nicht) im Mittelpunkt

Oliver Scholz

Mal ehrlich: auf dem TT mit dem Grossbildschirm zu arbeiten, macht unheimlich Spaß, oder? Man kann Fenster auf enorme Grössen aufblasen und Datenmengen darin darstellen, die auf einem normalen ST-Monitor nicht möglich wären. Allerdings hat die neue Freiheit auch ihren Preis: Dialoge und Alertboxen werden weiterhin zentriert dargestellt. Das sieht zwar gut aus, ist aber recht lästig; denn in der Regel tauchen Dialogboxen auf, weil man ein Drop-Down-Menü angewählt hat.

Und genau jene Drop-Down-Menüs kleben ganz klein und verloren in der linken oberen Bildschirmecke, genau wie die Icons. Das Resultat: ein andauerndes Hin- und Hersausen des Mauszeigers zwischen dem linken oberen Bildschirmbereich und der Bildschirmmitte. Und das ist auf dem guten Großbildschirm nicht wenig.

Die Lösung liegt auf der Hand: die Dialoge und Menüs müssen einander nähergebracht werden. Aber die Menüs liegen fest, sie würden in der Bildschirmmitte auch eher im Wege liegen. Also müssen die Dialoge in Richtung Menü wandern. Der naheliegendste Weg (den auch das Programm DeCenter beschreitet) ist der, den AES-Aufruf form_center() abzufangen und den Dialogen eine andere Bildschirmmitte vorzugaukeln. Dabei bietet sich an, den Programmen einen monochromen ST-Bildschirm mit 640 mal 400 Bildpunkten vorzuspiegeln, denn der ist dem Großbildschirm am ähnlichsten. Natürlich kann sich jeder die entsprechenden Konstanten im Programm selber nach eigenem Geschmack einrichten. Aber sie sollten nicht zu klein gewählt werden, weil manche Programmierer Dialogboxen programmieren, die eine volle 640-Pixel-Bildschirmbreite ausnutzen - der Effekt wäre, daß ein Teil der Dialogbox nicht dargestellt werden könnte.

Leider funktioniert DeCenter nur mit Programmen, die für AES-Aufrufe den Trap 2 benutzen. Aber da das ja der saubere Weg ist, klappt es mit den meisten Programmen problemlos. Nur solche Programme, die ihre Dialogboxen selbst zentrieren, reagieren nicht auf unsere Roßkur. Dazu gehört leider auch das Desktop; es springt die form_center()-Funktion direkt an, weshalb seine Dialogboxen weiterhin zentriert erscheinen. Alertboxen erscheinen ebenfalls weiterhin in der Bildschirmmitte, denn das AES springt seine eigene form_center() Routine natürlich direkt an. Wer auch die Alertboxen aus der Bildschirmmitte weghaben will, der muß auch den form_center() Aufruf abfangen, aus dem übergebenen String einen Dialogbaum aufbauen, diesen dann dem AES übergeben, aus dem Exitobjekt den Buttonindex berechnen und dann dem Aufrufer zurückgeben. Gar nicht so einfach also, aber nicht unmöglich.

Installation

Anzumerken ist hier, daß DeCenter erst ausgeführt werden kann, nachdem das AES bereits installiert ist, daher scheidet der Einsatz im AUTO-Ordner leider aus. Man kann DeCenter natürlich auch vor dem AES installieren, jedoch wird dann mit dem Starten des AES der Trap 2-Vektor wieder überschrieben. Der Erfolg: eine residente Speicherleiche ohne Funktion. Aber glücklicherweise kann das Desktop ja auch AUTO-GEM-Programme ausführen. Dazu wird DeCenter einmal angeklickt, dann als AUTO-GEM-Programm installiert und schließlich noch einmal die Arbeit gesichert. Beim nächsten Systemstart wird dann DeCenter automatisch ausgeführt.

Wer das nicht möchte, weil er z.B. bereits ein anderes Programm als AUTO-GEM angemeldet hat, kann DeCenter bei Bedarf natürlich auch von Hand installieren.

Zum Programm

Das Programm besteht im wesentlichen aus zwei Teilen: dem Installationsteil und dem residenten Trap Handler. Zunächst zum Installationsteil. Zuerst wird der nicht benötigte Speicher dem System zurückgegeben. Dann wird die Bildschirmauflösung geholt und geprüft, ob der Großbildschirm angeschlossen ist. Ist das nicht der Fall, wird eine entsprechende Meldung ausgegeben und das Programm beendet. Sonst wird die Installationsroutine aufgerufen. Das geschieht im Supervisormodus, weil auf den Trap #2-Systemvektor zugegriffen werden soll. Die Routine prüft nun mittels des XBRA-Protokolls, ob sich DeCenter bereits im Speicher befindet. Ist dies der Fall, kehrt install mit -1 zurück, und das Hauptprogramm terminiert mit einer Fehlermeldung. Ansonsten wird der neue Trap Handler installiert, das Hauptprogramm gibt den nicht benötigten Teil des Speichers wieder frei und hält nur den Trap Handler resident.

Der Trap Handler prüft bei jedem Aufruf, ob ein AES-Aufruf vorliegt, und wenn ja, ob das ein form_center() ist. Alles andere wird direkt an das AES weitergereicht. Die neue Routine holt sich die Baumadresse des Dialogs und die Adresse des intout[]-Arrays, dann die Breite und Höhe des Dialogs aus dem Dialogbaum. Darauf berechnet die Routine mit deren Hilfe die Koordinaten der linken oberen Ecke des Dialogs, trägt die Werte in den Dialog ein und gibt schließlich die entsprechenden Werte im intout[]-Array zurück.

Das Programm ist mit MAS68 geschrieben, und es sollte auch auf jedem anderen Assembler assemblierbar sein, sofern dann die SUPER-Direktive entfernt wird. Da das Programm recht maschinennah mit Traps und Registern hantiert, wäre ein C-Compiler hier wohl nicht angebracht gewesen. Und das resultierende Programm ist kürzer als schon der Startup Code gewesen wäre. Was schon das nächste Thema ist: das Programm muß ohne Startup-Datei (tcstart.o) gelinkt werden. Dazu wird der Linker direkt aufgerufen:

TLINK -S=0 -O=decenter.prg decenter.o

Dann sollte sich ein ausführbares Programm auf der Platte befinden. Bleibt mir nur noch, allen Benutzern des Großbildschirms viel Freude mit dem Gerät (vielleicht jetzt noch mehr!) zu wünschen.

*
*---------------------------------------------
* DeCenter Utility for the Atari TT
* by Oliver Scholz
* (c) MAXON 1991
*---------------------------------------------
                super

* ASCII Konstanten

CR              equ     13
LF              equ     10

* Großbildschirmauflösung

HIRES           equ     6

* AES Konstanten

Trap2           equ     $88
AES_MAGIC       equ     $C8
Form_Center     equ     54

* GEMDOS Konstanten

Gemdos          equ     1
Pterm0          equ     0
Cconws          equ     9
Ptermres        equ     $31
Mshrink         equ     $4A

* XBIOS Konstanten

Xbios           equ     14
Getrez          equ     4
Supexec         equ     38

* Konstanten fur Bildschirmgröße

XRES2           equ     320     * 640/2
YRES2           equ     209     * 400/2+9

* Anfang des residenten Bereichs 

res_anf:
        bra start

            .dc.b 'XBRA'
            .dc.b 'DCNT'        * XBRA-ID
old_trp:    .ds.l 1

* neuer Trap 2 Handler 

new_trp:
        cmp #AES_MAGIC,d0       * AES-Aufruf ?
        bne do_old              * nein...

        move.l a0,-(sp)         * A0 retten

        move.l d1,a0            * AES Parm. Block
        move.l (a0),a0          * Contrl Array
        cmp #Form_Center,(a0)   * Opcode 
        beq new_center

        move.l (sp)+,a0

do_old: move.l old_trp,-(sp)    * alte Routine 
        rts

* neue form_center() Routine

new_center:
        move.l (sp)+,a0
        movem.l d0-d1/a0-a2,-(sp)

        move.l d1,a0            * Parameterblock
        move.l 16(a0),a1        * addrin[] Array
        move.l 12(a0), a2       * intout[] Array

        move.l (a1),a0          * Baumadresse
        move #1,(a2)            * intout[0]

        move 20(a0),d1          * Baumbreite
        move d1,6(a2)           * nach intout[3]
        lsr #1,d1               * durch 2
        move #XRES2,d0          * X-Bildschirmmitte
        sub d1,d0               * Objekt X-Koordinate
        move d0,2(a2)           * nach intout[1]
        move d0,16(a0)          * in Baum eintragen

        move 22(a0),d1          * Baumhöhe
        move d1,8(a2)           * nach intout[4]
        lsr #1,d1               * durch 2
        move #YRES2,d0          * Y-Bildschirmmitte
        sub d1,d0               * Objekt Y-Koordinate
        move d0,4(a2)           * nach intout[2]
        move d0,18(a0)          * im Baum eintragen

        movem.l (sp)+,d0-d1/aO-a2
        rte                     * Ende des Traps

res_end:
*--------------- Ende des residenten Bereichs

* Beginn des eigentlichen Programms

start:  move.l sp,a5            * Stackpointer retten
        move.l 4(a5),a5         * Basepage Adr. holen
        move.l $c(a5),d0        * Codelänge
        add.l $14(a5),d0        * +Data
        add.l $lc(a5),d0        * +Bss
        add.l #512,d0           * +Stackspace/Basepage 
        move.l d0, d1
        add.l a5,d1             * Basepage+Length
        bclr #0,d1              * gerade machen
        move.l d1,sp            * Neuer SP
        move.l d0,-(sp)         * Programmlänge
        move.l a5,-(sp)         * Programmstart
        clr.w -(sp)             * Dummy
        move #Mshrink,-(sp)
        trap #Gemdos            * Speicher freigeben 
        add.l #12,sp            * Clean up stack

        move #Getrez,-(sp)      * erweiterte 
        trap #Xbios             * Auflösung abfragen
        addq.l #2,sp

        cmp #HIRES,d0           * Großbildschirm ?
        bne fail                * nein...

* neuen AES Aufruf installieren

        pea install
        move #Supexec,-(sp) 
        trap #Xbios
        addq.l #6,sp

* Installation erfolgreich ?

        tst d0
        bmi fail2               * nein...

        lea success,a0          * Meldung ausgeben
        move.l a0,-(sp)
        move #Cconws,-(sp)
        trap #Gemdos
        addq.l #6,sp

* angegebenen Teil des Programmes resident halten
* den Rest wieder freigeben und Programm beenden

        clr -(sp)               * kein Fehler
        move.l #256+res_end-res_anf,-(sp) 
        move #Ptermres,-(sp)
        trap #Gemdos

*---------------------------

* DeCenter schon im Speicher:
* nicht nochmal installieren

fail2:  lea already,a0
        bra print

* falsche Auflösung: nicht installieren

fail:   lea failure,a0          * Meldung ausgeben
print:  move.l a0,-(sp)
        move #Cconws,-(sp)
        trap #Gemdos
        addq.l #6,sp

        move #Pterm0,-(sp)      * Programm beenden
        trap #Gemdos

*---------------------------

* Installationsroutine: muß im Supervisormodus
* ausgeführt werden! (Zugriff auf Trap2 Vektor)

install:
        move.l Trap2,a0         * Alte AES Routine 
        move.l a0,old_trp       * schon mal merken

* nachsehen. ob DeCenter schon im Speicher ist

loop:   cmp.l #'XBRA',-12(a0)
        bne ok                  * kein XBRA Protokoll
        cmp.l #'DCNT',-8(a0)
        beq schon_da            * DeCenter da ?
        move.l -4(a0),a0        * nächste Routine
        bra loop

* neue Routine eintragen

ok:     move.l #new_trp,Trap2

        clr d0                  * Default: ok
        rts

* Installation fehlgeschlagen: DeCenter schon da 

schon_da:
        moveq #-1,d0            * Fehler anzeigen
        rts

        .data

* und die Meldungen. .

success:    .dc.b "DeCenter installiert"
            .dc.b CR,LF,0
failure     .dc.b "DeCenter nicht installiert" 
            .dc.b CR,LF,0
already:    .dc.b "DeCenter ist schon installiert"
            .dc.b CR,LF,0



Aus: ST-Computer 09 / 1991, Seite 79

Links

Copyright-Bestimmungen: siehe Über diese Seite