Kleine Hilfe für RSC-Dialoge in GFA BASIC

Dialoge ‘zu Fuß’ direkt zu erstellen, ist sehr mühsam. Eine sehr grosse Hilfe ist ein Resource Construction Set, das dem Programmierer erlaubt, Dialoge, Menüs und dergleichen sehr komfortabel am Bildschirm zu erstellen. Einen haken hat allerdings auch das schönste RCS: Die Verwendung von indizierten - Variablen (auch Arrays oder Felder genannt) bleibt dem Programmierer versagt.

Oftmals kommt es vor, daß bei Dialogen mehrere Objekte in ihrer Hauptfunktion gleich sind, aber das Programm mit anderen Parametern versorgen. Nehmen wir an, wir hätten einen Dialog, in den wir Werte eintragen können, z.B. Meßwertepaare. Bei 10 Wertepaaren wären das 20 (!!) Felder, die jeweils mit einer Variablen angesprochen werden. Also müssen 20 Zeilen geschrieben werden, um den Dialog in diesem Punkt auszuwerten, und 20 Zeilen, um die Felder vorzubesetzen -also 40 Zeilen bzw. mehr als eine halbe DIN A4-Seite. Mit indizierten Variablen hätten wir zwei kleine Schleifen von je 3 Zeilen.

Also lohnt es sich in einem solchen Fall, sich Gedanken darüber zu machen, wie die Überführung der Objektnamen in indizierte Variablen am besten und einfachsten zu machen ist.

In GFA BASIC 3.xx ist dieses Problem recht elegant zu lösen, gibt es doch den Befehl ABSOLUTE. Anfangs stand ich diesem Befehl äußerst skeptisch gegenüber. Was sollte es denn nützen, wenn ich damit eine Variable an einer bestimmten Adresse ansiedeln würde? Doch ich wurde schnell eines Besseren belehrt: Mit Hilfe von ABSOLUTE ist es möglich, Array-Elementen einen ‘Decknamen’ zu verpassen. Die Vorgehensweise ist denkbar einfach:

Ein kleines Beispiel:

OPTION BASE 0 
DIM x&(5) adr%=V:x&(0)
ABSOLUTE adr%+0,x0& !X&(0) 
ABSOLUTE adr%+2,x1& !X&(1) 
ABSOLUTE adr%+4,x2& !X&(2)
         "
         "
ABSOLUTE adr%+10,x5& !X&(5)

Das ist schon alles! Nun hört die Variable x&(0) auch auf den Namen x0&. Die Sprünge von 2 kommen zustande, da eine WORD-Variable 2 Bytes lang ist. Das nun folgende Programm nimmt dem Programmierer die Schreibarbeit ab, setzt OPTION BASE 0 voraus. In der Procedure ‘rom’ sähe das Beispiel so aus:

DATA x,0,5 
DATA *

GFA BASIC hat gegenüber Pascal oder C den Nachteil, keine Konstanten zu kennen, jeder Objektname verbraucht also zwei Bytes Speicherplatz (Verwendung von RSC2.PRG). Würden die Objektnummern in die entsprechenden Array-Elemente kopiert, so verdoppelte sich der Speicherplatz, zuzüglich der Deskriptoren. Durch den Kniff mit ABSOLUTE wird immerhin die Verdoppelung des Speicherplatzes verhindert.

Vorgehensweise in eigenen Programmen

Zunächst werden die Arrays dimensioniert und den Elementen die entsprechenden Namen zugewiesen. Dann werden die Namen auf ihre Werte gesetzt, ist die Resource einsatzbereit. Den zusätzlichen Speicherplatz, der benötigt wird, belegen nur die Felddeskriptoren.

Beim Programm selbst wurde auf jeden ‘Schnickschnack’ wie z.B. eine Fileselektorbox zur Eingabe des Dateinamens verzichtet, ads läßt sich ja leicht selbst einbauen. Die Namen für Prozedur und Datei müssen also direkt eingesetzt werden.

Sämtliche DIM- und ABSOLUTE-Anweisungen werden vom Programm in eine Prozedur, mit adr% als lokaler Variablen, verfrachtet. Das hat den Vorteil, daß die gesamte Procedure mit HELP auf eine Editorzeile zusammengeschrumpft werden kann und nicht mehr stört.

In Listing 1 ist das gesamte Programm, das so kurz wie möglich gehalten wurde, in Listing 2 sehen Sie einen Treiber und die Prozedur, die mit dem Programm aus Listing 1 erstellt wurde.

Literatur:

Engels/Görgens,
GFA BASIC 3.0 Handbuch,
GFA Systemtechnik GmbH, 1988

' (c) MAXON Computer GmbH
'
RESTORE 
DIM d$(200,3)
DIM k|(200,1) 
i|=0 
REPEAT 
    INC i|
    FOR k|=1 TO 3 
        READ d$(i|,k|)
        EXIT IF d$(i|,k|)="*"
    NEXT k|
    IF d$(i|,1)="*"
        INC k |
    ENDIF
UNTIL d$(i|,k|-1)=”*" 
n|=i|-1
'
FOR i|=1 TO n|
    k|(i|,0)=VAL(d$(i|,2)) 
    k|(i|,1)“VAL(d$(i|,3))
NEXT i|
'
OPEN "O",#1,"comput.LST"
PRINT #1,"PRO test"
PRINT #1,"LOC adr%"
FOR i|=1 TO n|
    PRINT #1,"DIM "+d$(i|,1)+"&(";k|(i|,1);")"
NEXT i|
PRINT #1,"'"
FOR i|=1 TO n|
    PRINT #1,"adr%=V:"+d$(i|,1)+"&(0)"
    FOR k|=k|(i|,0) TO k|(i|,1)
        PRINT #1,"ABSOLUTE "+d$(i|,1);k|;adr%+";k|*2;"  !";d$(i|,1);"&(";k|;")"
    NEXT k|
NEXT i|
PRINT #1,"RET"
CLOSE
'
PROCEDURE rom 
    DATA skal,1,14 
    DATA lin,1,14 
    DATA *
RETURN

    test
    PRINT skal12& 
    skal&(12)=-123 
    PRINT skal12&
    '
    PRINT
    '
    PRINT lin&(3) 
    lin3&=555 
    PRINT lin&(3)
    END
    '
    PROCEDURE test 
        LOCAL adr%
        DIM skal&(14)
        DIM lin&(14)
        '
        adr%=V:skal&(0)
        ABSOLUTE skal1&,adr%+2 !skal&(1) 
        ABSOLUTE skal2&,adr%+4 !skal&(2) 
        ABSOLUTE skal3&,adr%+6 !skal&(3) 
        ABSOLUTE skal4&,adr%+8 !skal&(4) 
        ABSOLUTE skal5&,adr%+10 !skal&(5) 
        ABSOLUTE skal6&,adr%+12 !skal&(6) 
        ABSOLUTE skal7&,adr%+14 !skal&(7) 
        ABSOLUTE skal8&,adr%+16 !skal&(8) 
        ABSOLUTE skal9&,adr%+18 !skal&(9) 
        ABSOLUTE skal10&,adr%+20 !skal&(10) 
        ABSOLUTE skal11&,adr%+22 !skal&(11) 
        ABSOLUTE skal12&,adr%+24 !skal&(12) 
        ABSOLUTE skal13&,adr%+26 !skal&(13) 
        ABSOLUTE skal14&,adr%+28 !skal&(14) 
        adr%=V:lin&(0)
        ABSOLUTE lin1&,adr%+2 !lin&(1) 
        ABSOLUTE lin2&,adr%+4 !lin&(2) 
        ABSOLUTE lin3&,adr%+6 !lin&(3) 
        ABSOLUTE lin4&,adr%+8 !lint(4) 
        ABSOLUTE lin5&,adr%+10 !lin&(5) 
        ABSOLUTE lin6&,adr%+12 !lin&(6) 
        ABSOLUTE lin7&,adr%+14 !lin&(7) 
        ABSOLUTE lin8&,adr%+16 !lin&(8) 
        ABSOLUTE lin9&,adr%+18 !lin&(9) 
        ABSOLUTE lin10&,adr%+20 !lin&(10) 
        ABSOLUTE lin11&,adr%+22 !lin&(11) 
        ABSOLUTE lin12&,adr%+24 !lin&(12) 
        ABSOLUTE lin13&,adr%+26 !lin&(13) 
        ABSOLUTE lin14&,adr%+28 !lin&(14) 
    RETURN

T.W. Müller
Aus: ST-Computer 10 / 1989, Seite 93

Links

Copyright-Bestimmungen: siehe Über diese Seite