Retter: Versicherung mal anders

Als Hobbyprogrammierer habe ich schon einige grössere Programme auf die Beine gestellt; doch kam es immer vor, dass irgendwo in diesen Programmen noch Fehler versteckt waren, die sich erst nach mehrmaligem Ausprobieren plötzlich zeigten. meistens hatte ein Anwender gerade einige Zeit gearbeitet, als plötzlich ein Fehler auftrat, die Fehlerabfangroutine versagte und der Anwender sich zu seiner grössten Verwunderung auf dem Desktop wiederfand, während ihm einfiel, dass er noch nicht gespeichert hatte. Obwohl die Daten sich zu diesem Zeitpunkt noch im Arbeitsspeicher befanden, mussten die Anwender sich von neuem ans wer machen - bis heute.

Denn seit heute sind meine Programme mit einem neuen System ausgestattet, das ich Ihnen hier vorstelle. Es besteht aus einem Accessory (also einem Programm, das beim Booten geladen wird, und in jedem Programm, das eine Menüzeile hat, also auch dem Desktop, aufgerufen werden kann) und einer Routine, die in das Programm, dessen Daten geschützt werden sollen, eingebaut wird. Diese Routine übergibt dem Accessory Startadresse und Länge des Bereiches, der im Notfall gespeichert werden soll.

Tritt dieser Notfall ein, klickt der Benutzer das Accessory an (das sich ungefähr dort befindet, wo auch Kontrollfeld u.ä. zu finden sind), und die Daten werden in der Datei „\DA-TEN.ASC“ gespeichert.

Der „Einbau“

Wenn Sie eigene Programme mit dem System versehen wollen, geben Sie das untenstehende Accessory ein und compilieren es als Accessory. Wichtig: es muß jetzt den Namen „RETTER.PRG“ tragen! Wenn Sie mit GFA-B ASIC 2.0 arbeiten, compilieren Sie es normal und behandeln es dann mit dem „Accessory-Maker“. (Tippen Sie das Listing ein, starten Sie das Programm und wählen Sie „RETTER.PRG“ in der Dateiauswahlbox) Geben Sie dann die Aufruf-Routine ein und bauen Sie sie nach dem angegebenen Beispiel in Ihr Programm ein. Die Daten, die gespeichert werden, müssen sich in einem geschlossenen Bereich befinden, dessen Anfangsadresse und Länge der Routine beim Aufruf übergeben werden. Leider verfügt GFA-BASIC 2.0 nicht über den einfachen Aufruf der GEM-Befehle wie die 3.5-Version. Sie müssen bei Verwendung der 2.0-Version deshalb die mit REM versehenen Befehle eingeben und jeweils den ersten Befehl vor einem solchen Block von REM-Befehlen weglassen.

Der tiefere Einblick

Sollten Sie zu den „Banausen“ gehören, die sich nicht für die tieferen Geheimnisse der Programmierung interessieren, so können Sie an dieser Stelle getrost aufhören zu lesen.

Zum Accessory: es meldet sich nach dem Start sofort mit der GEM-Funktion MENU_REGISTER unter dem Titel „Datenrettung“ an und wartet dann in einer Endlosschleife auf einen Aufruf oder die Sendung der Anfangsadresse und Länge des zu speichernden Bereiches. Das Warten übernimmt der Befehl „EVNT_MESAG“, dem ein 16 Bytes großer Puffer (hier in Form von 4 Langwörtern) übergeben werden muß. Das erste Wort (=2 Bytes) enthält den Nachrichtentyp. Wird beispielsweise das Accessory angeklickt, steht hier der Wert 40; bekommt das Accessory Daten, so erhält es hier den Wert 42 (den ich ausgesucht habe). Das Accessory „weiß“ dann, daß es im 4. und 5. Wort des Puffers [=Puffer%(2)l die Startadresse und im 6. und 7. Wort [=Puffer%(3)] die Länge erhält. (Damit auch große Werte übergeben werden können, wurden für diese Parameter je 2 Wörter gewählt - wir haben ja Platz) Die Werte in den restlichen Wörtern sind für uns unerheblich.

Zur Routine: Sie muß mit der GEM-Funktion Appl_Find die Identifikationsnummer des Accessories finden, um ihm anschließend mittels Appl_write eine Nachricht zukommen zu lassen. Diese Nachricht enthält nun genau die Informationen (42, Startadresse, Länge), auf die das Accessory wartet.

Wenn Sie die Abfrage der Nachricht 42 sowie die Prozeduren im Accessory weglassen, können Sie es als normales Accessory für andere Zwecke gebrauchen. Die Prozedur, die nach dem Anklicken des Accessories ausgeführt werden soll, nennen Sie bitte Open ac.

Literatur:

[1] GFA-Clubnachrichten,Ausg. 1/2 und 3/4 1990

[2] Data Becker: Atari ST intern

' Accessory "RETTER" des Datenrettungssystems 
' by Sebastian Mödersheim 
' (c) 1991 MAXON Computer
'
RESERVE 33000 ! wir brauchen etwas Platz
ON BREAK CONT ! Abbruch nicht möglich
DIM puffer%(3) ! 4 Longwords = 16 Bytes
eintrag$=" Datenrettung" ! Accessory anmelden
ap_id%=APPL_INIT() ! Dazu brauchen wir unsere Identifikationsnummer 
REM ap_id%=Dpeek(Lpeek(gb+4)+4) 
dummy%= MENU_REGISTER(ap_id%,eintrag$)
REM DPOKE GINTIN,DPEEK(LPEEK(GB+4)+4)
REM LPOKE ADDRIN,VARPTR(eintrag$)
REM GEMSYS 35
'
DO
    ~EVNT_MESAG(V:puffer%(0)) ! Auf Aufruf und Daten warten 
    REM LPOKE ADDRIN,VARPTR(puffer%(0))
    REM GEMSYS 23
    ' Wort 0: Nachrichtentyp (muß hier 40 oder 42 sein)
    '         40: Accessory wurde angeklickt 
    '         42: Ein Programm will uns etwas übergeben
    ' Wort 1: Identifikationsnummer des sendenden Programmes
    ' Wort 2: <>0 bedeutet, die Nachricht hat Überlänge
    IF (puffer%(0) DIV 65536)=40 THEN ! Accessory 
        @open_ac ! wurde angeklickt
    ENDIF
    IF (puffer%(0) DIV 65536)=42 THEN ! Daten werden 
        @get_datas ! übergeben
    ENDIF 
LOOP
'
PROCEDURE open_ac
    IF begin%=0 ! Wenn Daten unkorrekt oder noch gar nicht
        '               übergeben wurden 
        ALERT 1,"Hier Datenretter.|Mir liegen keine|korrekten Daten vor",1," ... ",dummy%
    ELSE
        ALERT 1,"Hier Datenretter.|Ich kann Ihre|Daten jetzt speichern",1,"Na los|Halt",dummy%
        IF dummy%=1
            BSAVE "\Daten.asc",begin%,laenge% 
        ENDIF 
    ENDIF 
RETURN
'
PROCEDURE get_datas 
    begin%=puffer%(2) 
    laenge%=puffer%(3)
    ' Wort 3+4 (=ein Langwort): Startadresse 
    ' Wort 5+6                : Länge
    IF begin%=0 OR laenge%=0 !Da kann was nicht stimmen ...
        ALERT 1,"Hier Datenretter:|Habe fehlerhafte Daten|erhalten",1," Aha? ",dummy%
        begin%=0
    ELSE
        ALERT 1,"Hier Datenretter:|Habe korrekte Daten|erhalten",1," Schön ", dummy%
    ENDIF
RETURN
' Einbaumodul des Datenrettungssystems 
' by Sebastian Mödersheim 
' (c) 1991 MAXON Computer
' Hinweise:
' Die Daten, die im Bedarfsfall gerettet werden,
' müssen in einem Block liegen. Der Routine
' "CALL_SAVER, die am Anfang eines Programmes auf-
' gerufen wird, bekommt als Parameter Startadresse
' und Länge des Blockes übergeben.
'
' Beispiel für zu rettende Daten 
Unsinn$="Gespeichert oder nicht gespeichert."
Unsinn$=Unsinn$+" Das ist doch wohl keine Frage."
GOSUB call_saver(VARPTR(Unsinn$),LEN(Unsinn$))
'
PROCEDURE call_saver(begin%,len%)
    '
    sende_id%=APPL_INIT()   ! Unsere Identifikations-
    REM GEMSYS 10           ! nummer
    REM sende_id%=DPEEK(GINTOUT)
    '
    ziel$="RETTER "             ! Zielidentifikations-
    ziel_id%=APPL__FIND (ziel$) ! nummer 
    REM LPOKE ADDRIN,VARPTR(zielS)
    REM GEMSYS 13
    REM ziel_id%=DPEEK(GINTOUT)
    '
    IF ziel_id%=-1
        ALERT 1,"Datenretter|nicht gefunden",1, " ... ",dummy%
        GOTO tschuess 
    ENDIF
    '
    DIM puffer%(3) ! Nachricht 
    puffer%(0)=42*65536+sende_id% 
    puffer%(2)=begin% 
    puffer%(3)=len%
    '
    dummy%=APPL_WRITE (ziel_id%,16,varptr(puffer%(0)))
    REM DPOKE GINTIN,ziel_id% ■ Nachricht senden
    REM DPOKE GINTIN+2,16
    REM LPOKE ADDRIN,VARPTR(puffer%(0))
    REM GEMSYS 12
    REM dummy%=DPEEK(GINTOUT)
    '
    IF dummy%=-1
        ALERT 1,"Fehler bei der|Datenübermittlung",1," ... ",dummy%
        GOTO tschuess 
    ENDIF
    '
    ON MENU GOSUB nix ! Dieses Spielchen ist nötig,
    FOR dummy%=0 TO 10 ! da verschiedene Programme 
        ON MENU ! sonst verrückt spielen ...
    NEXT dummy% 
    tschuess:
RETURN

PROCEDURE nix ! Gehört zum Sendemodul
RETURN


' Der Accessorymaker
' by Sebastian Mödersheim
' (c) 1991 MAXON Computer
'
Pfad$="\*.*"
Fileselect Pfad$,"",Datei$
If Datei$<>"" And Right$(Datei$,3)="PRG"
    ' Wurde ein Programm angewählt?
    Open "U",#1,Datei$ ! Öffnen 
    Seek #1,28 ! und ab Stelle 28 die Daten
    Restore Inf ! schreiben
    Read Datum%
    While Not Datum%=-1 
        Out #1,Datum%
        Read Datum%
    Wend
    Seek #1,237 ! ... und an 237 noch was
    Read Datum%
    Out 1,Datum%
    Close #1 ! ... und fertig
    Name Datei$ As Left$(Datei$,Len(Datei$)-3)+"ACC"
    Print "Umwandlung vorgenommen"
Endif 
Inf:
Data 75,250,254,254,96,6,27,102,27,118,0,0, 
Data 79,237,1,0,-1,54

Sebastian Mödersheim
Aus: ST-Computer 01 / 1992, Seite 88

Links

Copyright-Bestimmungen: siehe Über diese Seite