Reine Existenzfrage

Heute präsentieren wir Ihnen unter anderem eine Methode, mit der ein Programm feststellt, ob es aus dem Auto-Ordner oder vom Desktop aus gestartet wurde. Die Idee zu diesem Programm entstand, als wir Julian Reschkes »Bigscreen« veröffentlichten. Bigscreen durfte nur vom Auto-Ordner aus, also bei nicht initialisiertem AES, eine Installation vornehmen. Doch leider erkannte das Programm nicht, ob sein Start während des Boot-Vorgangs durch das TOS oder im Desktop durch den Benutzer erfolgt war. Beim Start vom Desktop aus stürzte »Bigscreen« gnadenlos ab, und nur der Druck auf die Reset-Taste rief den ST ins Leben zurück.

Wie kann dies ein Programm feststellen? Eines ist charakteristisch für alle Programme, die aus dem Auto-Ordner starten sollen: Sie müssen auf sämtliche AES-Routinen verzichten, denn das AES (»Application Environment System«) installiert der ST erst beim Start des Desktop, also erst nachdem alle Auto-Ordner-Programme ausgeführt sind. Accessories aktiviert der ST auch erst, wenn das AES bereits vollständig zugriffsbereit ist. Wenn ein Programm feststellen möchte, ob es aus dem Auto-Ordner startet, muß es sich deshalb erkundigen, ob es freien Zugriff auf die AES-Routinen hat. Dies erledigen viele Programme, indem sie sich vergewissern, daß der Line-F-Dispatcher installiert ist, den das AES auf allen älteren Computern nach dem Booten installiert.

Auf älteren Geräten genügte es deshalb völlig, das oberste Byte der Speicherzelle 44 (hex. $2C, Line-F-Vektor) zu überprüfen. Enthielt diese Speicherzelle einen anderen Wert als 0, so bedeutete das daß das Programm im Auto-Ordner lag. Seit Atari den STE mit seinem TOS 1.6 verkauft, ist diese Methode nicht mehr zuverlässig. Der Grund: TOS 1.6 berührt den Line-F-Vektor gar nicht mehr. Viele Auto-Ordner-Programme dürften daher auf dem STE eigenartige Reaktionen zeigen. Die Systemprogrammierer bei Atari benutzen deshalb eine andere Methode, die auf allen Computern funktioniert: Das Programm ruft zu Beginn die AES-Funktion »appl_init« auf. Im AES-Globalfeld erhalten Sie als ersten Eintrag de verwendete AES-Versionsnummer. Ist das AES aber noch gar nicht zugriffsbereit, so kann es »appl_init« nicht ordnungsgemäß ausführen und kehrt unverrichteter Dinge ins Programm zurück. In diesem Fall ist der erste Globalfeld-Eintrag 0. Somit kann das Programm sicher davon ausgehen, daß es im Auto-Ordner gestartet wurde.

Beispiellistings in Assembler (Listing 1) und C (Listing 2) zeigen die Vorgehensweise. Wir entwickelten das Assembler-Programm mit dem Turbo-Ass 1.12 und das C-Listing mit dem Turbo-C 1.1. Anpassungen an andere Compiler und Sprachen dürften keine Probleme bereiten. Wie wir schon in der Oktober-Ausgabe berichteten, kann es bei Zeichenausgaben durch Interruptroutinen zu Problemen mit der eingebauten VT-52-Terminalemulation des Atari kommen [11. Diese treten auf, wenn der ST durch die Ausgabe eines »Escape«-Zeichens (ASCII 27, hex. $1B) eine Emulationssequenz einleitet, dann aber durch einen Interrupt unterbricht und in der Interruptroutine ein Zeichen ausgibt. Der ST betrachtet dann die Sequenz als abgeschlossen und führt sie deshalb nicht so aus, wie dies gewünscht war. Bei diesem Problem hilft uns die Systemvariable »con_state« weiter. Sie finden diese Variable an der Speicheradresse 1192 (hex. $4A8). Diese Speicheradresse benutzt der Computer als Zeiger auf Ausgaberoutinen. Wenn die auszugebende Zeichenfolge das Escape-Zeichen enthält, verschiebt der Atari diesen Zeiger und leitet damit eine Emulationssequenz ein. So können Sie anhand von »con_state« erkennen, ob der Interrupt während einer VT-52-Sequenz aufgetreten ist. Wie geht das in der Praxis vor sich?

Bei der Installation einer Interruptroutine, beispielsweise für den VBL, lassen Sie Ihr Programm einige Zeichen, wie etwa Zeilenvorschübe, Leerzeichen oder eine Copyright-Meldung ausgeben. Dazu verwenden Sie in Assembler am einfachsten GEMDOS 9 »Cconws()«. Die Hochsprachen verwenden fast ausnahmslos diese Routine.

GFA-Basic verwendet übrigens eine eigene Ausgaberoutine, die uns an dieser Stelle jedoch nicht weiter interessiert. Nach Ausgabe dieser Zeichen können Sie ziemlich sicher sein, daß keine VT-52-Emulation stattfindet. Daraufhin kopieren Sie den Inhalt von »con_state« in das BSS Ihres Programmes. Beachten Sie, daß »con_state« als Zeiger ein Langwort ist. Jetzt weiß Ihr Programm, auf welche Speicherzelle »con_state« zeigen muß, wenn keine Emulationssequenz eingeleitet ist. Die Interruptroutine Ihres Programmes muß nun, sobald TOS sie aufruft, erst einmal den gespeicherten Wert von »con_state« mit dem aktuellen vergleichen. Stimmen sie überein, so darf die Interruptroutine bedenkenlos Zeichen über BIOS oder XBIOS ausgeben. Ergibt sich zwischen dem gespeicherten und dem aktuellen Wert eine Differenz, dann unterbricht Ihre Routine eine VT-52-Emulation und darf deswegen keinesfalls Zeichen schreiben.

Die neue Version des in Ausgabe 10/89 vorgestellten »Carrier-Detectors« berücksichtigt dies [1]. Aus Platzgründen veröffentlichen wir dieses Programm nur auf unserer Leserservice-Diskette. Leider entstehen mit Ausgabe-Beschleunigern wie beispielsweise »Turbo ST« oder »Quick ST« Probleme. Besonders Turbo ST hält sich nicht an die Dokumentation. Wir erwarten allerdings immer noch die neue Version 1.7 von Quick ST. Für diese Version haben die Programmierer die Beseitigung des Problems bereits angekündigt. ».TTP«-Programme haben die Eigenschaft, nach dem Start nach einer eingegebenen Kommandozeile zu suchen. Vielen Basic-Programmierern scheint aber unbekannt zu sein, daß die Kommandozeile auch in Basic-Compilaten nutzbar ist. Sie liegt nach dem Start des Programmes 128 (hex. $80) Bytes hinter der Anfangsadresse der Basepage. Die Kommandozeile beginnt erst einmal mit einem Byte, das die Länge des Kommandostrings angibt. Ab Byte 129 (hex. $81) beginnt dann die eigentliche Kommandozeile, deren String nullterminiert ist. In Basic empfiehlt es sich, zunächst einmal die Kommandozeile in eine Stringvariable umzukopieren. Dort kann Ihr Programm diese jederzeit verarbeiten. Ein kleines Anwendungsbeispiel zeigt unser Listing 3. Der GFA-Basic-Interpreter benutzt die Kommandozeile übrigens auch. Findet er in der Kommandozeile seiner Basepage einen Eintrag, so versucht er, eine Basic-Datei des angegebenen Namens zu laden und zu starten. So können Sie den Interpreter im Desktop als Anwendung anmelden (TOS 1.4). Wenn Sie daraufhin ein Programm mit der Extension ».GFA« anklicken, sollte GEM automatisch den Interpreter starten, der dann seinerseits das gewählte GFA-Basic-Programm ausführt. (ba)

Quellennachweis:
[1] Laurenz Prüßner, »Verbindung erkannt - Gefahr gebannt«, ST-Magazin 10/1989, Seiten 62 ff.

Listing 1: Dieses Assembler-Programm testet, ob es aus dem Auto-Ordner oder aus dem Desktop gestartet wurde

; Prüft, ob das Program im AUTO-Ordner gestartet wurde.
; Geschrieben am 16.11.89 von Laurenz Prüßner.
; Funktioniert jetzt auch mit STEs und FPU-Zusätzen!
; Sprache: 68000-Assembler, Turbo-Ass 1.1

; Definitionen:
Show_Mouse:	EQU	$A009
Hide_Mouse:	EQU	$AOOA

TEXT
DC.W	Hide_Mouse
	move.l	#$0A0001,control	; appl_init
	move.l	#aes_pb, D1
	move.w	#$C8, A0
	trap	#2
	tst.b	global	; AES installiert?
	bne.s	Nicht	; Nope!

	pea	AUTO(PC)	; Jep!
Abgang:
	move.w	#9, -(SP)
	trap	#1
	addq.l	#6, SP
	move.b	#$13, control+1	; appl_exit
	move.l	#aes_pb, D1
	move.w	#$C8, D0
	trap	#2
	DC.W	Show_Mouse
	clr.w	-(SP)	; Programm beenden
	trap	#1
Nicht:
	pea	NAUTO(PC)
	bra.s	Abgang
DATA
AUTO:	DC.B	$1B, $45, $0A, $0A, $0A, $0A, $0A
	DC.B	‚Ich bin im AUTO-Ordner gestar‘
	DC.B	‚tet worden.‘, $0A, $0D, $00
	EVEN
NAUTO:	DC.B	$1B, $45, $0A, $0A, $0A, $0A, $0A
	DC.B	‚Ich bin nicht im AUTO-Ordner ge‘
	DC.B	‚startet worden.‘, $0A, $0D, $00
aes_pb:	DC.L	control, global, int_in
	DC.L	int_out, addr_in, addr_out
BSS
control:	DS.W	5	; Die AES-Variablen
global:	DS.W	15
int_in:	DS.W	16
int_out:	DS.W	7
addr_in:	DS.L	3
addr_out:	DS.L	1
END

Listing 2: Dieses C-Progromm stellt fest, ob sein Start aus dem Auto Ordner oder aus dem Desktop erfolgte

/* AUTO-Ordner-Erkennung in C. Funktioniert jetzt auch
   mit dem STE problemlos. (C) PP‘89.
   Geschrieben von Laurenz Prüßner am 17.11.1989.
   Compiler: Turbo C 1.1  */

#include <aes.h>
#include <stdio.h>
#include <string.h>

int *Pointer;

main()
{
	Pointer = _GemParBlk.global;
	appl_init();
	if ( *Pointer == 0)
		puts („Ich wurde im AUTO-Ordner gestartet.“);
	else
		puts („Ich wurde nicht im AUTO-Ordner gestartet.“);
	appl_exit();
	return 0;
}
Listing 3: Kommandozeilen erkennen unter GFA-Basic

´ Gibt die Kommandozeile von TTP-
´ Kompilaten aus. (C) PP‘89
´ GFA-Basic, L. Prüßner
a%=PEEK(BASEPAGE + &H80)
IF a%
	FOR f%=1 TO a%
		a$=a$+CHR$(PEEK(BASEPAGE+&H80+f%))
	NEXT A
	PRINT a$
ELSE
	PRINT „Keine Kommandozeile Übergeben!“
ENDIF
END

Laurenz Prüßner
Aus: ST-Magazin 02 / 1990, Seite 58

Links

Copyright-Bestimmungen: siehe Über diese Seite