Unterschiede in Rechner- & TOS-Versionen

In diesem Artikel erfahren Sie, was Sie beachten müssen, damit Ihre Programme auf allen Rechnertypen (ST, STE und TT) und unter allen Betriebssystemversionen lauffähig sind; Sie also ‘sauber’ auf ATARI-Rechnern programmieren.

Selbst ein Anwender, der die ST-Entwicklung seit 1985 mitverfolgt hat, wird die Änderungen und Neuerungen, die das ATARI-Betriebssystem erfahren hat, bis auf die größte Neuerung, das Desktop (STE 2.05, TT 3.01), nicht sehr umfangreich nennen. Auch das Desktop des ST wurde bereits durch Zusatzprogramme wie Neodesk oder das Shareware-Produkt Gemini in den gebotenen Möglichkeiten erweitert, die auch deshalb von vielen weiterhin verwendet werden. Die Software-Entwickler brachten auf allen Gebieten sehr interessante und brauchbare Produkte zustande. Doch eines war fast bei jeder Entwicklung mehr oder weniger stark zu beobachten: Alles wurde weniger auf Einheitlichkeit ausgelegt als auf Ablaufgeschwindigkeit. Am deutlichsten ist dies auch heute noch bei Editor- und Textverarbeitungsprogrammen zu spüren. Wer erinnert sich nicht an den sagenhaft schnellen Tempus-Editor und kurz danach an sein um ein Vielfaches an Scroll-Geschwindigkeit gesteigertes Upgrade? Doch wie konnten solche Geschwindigkeiten erreicht werden? Waren doch die Urvorbilder wie 1ST_WORD wahre Krücken in puncto Text-Scrolling.

Warum die Betriebssystemfunktionen nutzen, wenn man es selbst viel besser nachprogrammieren kann? So dachten und handelten viele Programmentwickler damals und einige auch noch heute. Sehr zum Ärgernis der Hersteller von Hardware-Erweiterungen wie beispielsweise von Grafikkarten und Turboboards, die die Inkompatibilitäten, zum Teil auch des Betriebssystems selbst, am deutlichsten zu spüren bekamen.

Das Zauberwort ist LINEA

Es handelt sich dabei um eine Sammlung von hardwarespezifischen Grafikfunktionen, auf die die VDI-Betriebssystemfunktionen zurückgreifen. Direkt nach der offiziellen Dokumentation von ATARI wurden sehr viele Programme dahingehend umgestellt oder neuprogrammiert. Heute weiß man, daß es besser gewesen wäre, wenn ATARI stattdessen offizielle Programmierrichtlinien veröffentlicht hätte, was übrigens bis heute nicht geschehen ist. Mit der Einführung der ATARI-TT-Geräte verschwanden auch die LINEA-Funktionen. Es handelte sich eben nicht, wie beim VDI-Gerätetreiber, um eine geräteunabhängige Funktionssammlung. Auch ATARI hat den Fehler eingestanden und rät nun jedem Software-Entwickler tunlichst die Finger von den hardwarespezifischen Betriebssystemroutinen zu lassen. Nachzulesen ist dies in der allerneusten Ausgabe des ATARI Profibuches für den ST-STE-TT vom Sybex Verlag. Dort sind nun auch zum ersten Mal die XBIOS-Funktionen, die die Video-Hardware betreffen, als nur auf die Rechnergrundkonfiguration (ohne Grafikzusatz-Hardware) bezogene Funktionen deklariert. Für die Programmierer bedeutet dies, daß sie zwar wissen dürfen, was die Funktionen bewirken, aber der Einsatz in eigenen Programmen eine Inkompatibilitätgarantie auf ATARI-Computern mit geänderten Grafiksystemen darstellt.

Weitere Schwierigkeiten bereitet der Motorola-68030-Prozessor im TT oder auf Turboboard für Programme, die einen eigenen Exceptionhandler installieren und die Prozessoränderung nicht beachten. Die im folgenden aufgeführten Punkte sollten unbedingt vor der Entwicklung systemunabhängiger Software bedacht werden. Die danach beschriebenen Problemlösungen bieten wir Ihnen als Alternative an.

...

Long stack,*cookie;
Long bigproz = 0L;
...
sack = Super(0L); 	/* I.d.Supervisormodus schalten */ 
cookie = *((Long **)0x5A0L); /*Cookie-Zeiger holen */ 
Super((void *)sack); /* Wieder in den User-Modus */

if(cookie != 0L) /* ist ein Cookie angelegt */
	{
	do
		{
		if((cookie[0] == '_CPU') && (cookie[1] > 0L))
			{
			bigproz = cookie[1]; /* Prozessor > 68000 */ 
			break;
			}
		cookie = &(cookie[2]); /* nächster Cookie */
		} while(cookie[ -2]); /* war Null-Cookie? */
	}

Listing 1: Prozessortypermittlung an Hand des Cookie-Jar-Eintrags

	;--- Feststellen, ob 68010/20/30/40 installiert ------
	;

		pea		illegaltst(pc)
		move.w #4,-(sp) ; Illegal Vector
		move.w #5,-(sp) ; Setexc
		trap	#BIOS
		addq.l	#8,sp
		moveq	#-1,bigproz ; Ist da
		move	CCR,d1		; 68000 -> Illegal Instr. sonst ohne Effekt
		move.l	d0,-(sp)	; alten Vektor wieder einsetzen
		move.w	#4,-(sp)	; Illegal Vector
		move.w	#5,-(sp)	; Setexc
		trap	#BIOS
		addq.l	#8,sp
		bra	weiter

	illegaltst:
		clr.w bigproz ; Illegal -> 68000 im System 
		addq.l #2,2(sp) ; PC Auf nächsten Befehl setzen 
		rte

Listing 2: Prozessortypermittlung bei älteren TOS-Versionen

	; Exception-Routine:

			movea.l a7,a0 
			tst.w	bigproz
			beq.b	68000	; normaler 68000
			addq.l	#8,a0	; falls 68010 -> 68XXX Stackframe korrigieren
			bra.b	weiter 
	68000:	addq.l	#6,a0
			bra.b	weiter

	weiter:		; jetzt können die Parameter korrekt vom 
				; Stapel (in A0) geholt werden!

	...

Listing 3: Beispiel zur Stackframe-Behandlung bei verschiedenen Prozessortypen

Prozessortyp?

Seit TOS 1.06 existieren die Cookie-Jar-Einträge. Dabei handelt es sich um eine Systemvariable, die auf eine Tabelle mit Kennungen und Werten zeigt. Jeder Tabelleneintrag ist ein Paar von Langwörtern - ein Langwort für die eindeutige Kennung des Cookies nd eines für den zu übermittelnden Wert.

Will man den Prozessortyp ermitteln, muß man die Cookie-Jar-Systemvariable auslesen und die Tabelle durchsuchen, bis man auf das Ende trifft, das durch eine Null gekennzeichnet ist. Der Wert der Null-Kennzeichnung ist die in der Cookie-Tabelle erfaßbare Anzahl an Einträgen. Ein Bespiel dazu finden Sie in Listing 1. Zur Ermittlung des Prozessortyp bei einer älteren TOS-Version sehen Sie eine nicht ganz so einfache Methode in Listing 2.

Zur Ermittlung wird zuerst eine Exception-Routine illegaltst installiert, die bei einer illegalen Instruction aufgerufen werden soll. Danach wird der Befehl CCR ausgeführt, der erst ab dem 68010 im Befehlssatz enthalten ist. Startet man das Programm auf inem System mit einem normalen 68000-Prozessor, wird eine Illegal-Instruction-Exception (Ausnahmebehandlung mittels Interrupt; siehe Artikel ‘Timer und Interrups’ in diesem Sonderheft) ausgelöst, die zuvor installierte Routine angesprungen und die Variable bigproz gelöscht.

Was hat man nun davon, daß man den Prozessortyp kennt? Bei manchen Programmierproblemen ist es wichtig, den Prozessor genau zu kennen. Zum Beispiel, wenn ein eigener Exception-Handler installiert werden soll, da hierbei auf den um 2 Byte größeren Stackframe der Prozessoren ab 68010 reagiert werden muß. (siehe Listing 3)

Video-Hardware

Die allergrößte Schwierigkeit war und ist die Beachtung und entsprechende Reaktion auf verschiedene Video-Hardware. Mittlerweile gibt es ein sehr reichhaltiges Angebot an Grafikerweiterungen und Farbgrafikkarten, die alle über eigene Treiber-Software verfügen, die speziell an die Hardware-Eigenschaften angepaßt ist.

Was immer noch sehr oft falsch gemacht wird, ist die Ermittlung der Bildschirmauflösung. Zuverlässig kann dies nur mit den Funktionen open_screen-workstation (VDI1) oder mit open_virtual-screenworkstation (VDI 100) gemacht werden. Diese Funktionen müssen allerdings immer aufgerufen werden, wenn Programme die Grafikfunktionen des VDI-Treibers nutzen wollen. Auch bei BASIC-Programmen muß dies geschehen. Die Rückgabewerte in GFA-BASIC können aus dem vorgegebenen Array WORK_OUT ausgelesen werden. Listing 4 zeigt dies in C am Beispiel einer open_vwork()-Routine. Die Rückgabewerte, die nach dem Aufruf im work_out-Array stehen, können Sie der Tabelle 1 entnehmen.

Da diese Informationen noch lange nicht ausreichend sind, beispielsweise fehlt die Information zur Farbtiefe (Bitplanes), existiert die Funktion vq_extnd (VDI 102), mit der auch die erweiterte Parameterliste ermittelt werden kann (siehe Tabelle 2)

GFA-BASIC

In GFA-BASIC-Programmen lassen sich drei Fehler sehr häufig beobachten:

Der Befehl BITBLT ist in der GFA-BASIC-Dokumentation leider sehr dürftig erklärt. Will man ihn benutzen, müssen unzählige Parameter in verschiedene Arrays eingetragen werden. Einfacher hat man es mit den Befehlen SGET und SPUT. Mit diesen beiden Befehlen ist es sehr einfach möglich, den gesamten Bildschirm in einem String abzuspeichern und bei Bedarf wieder anzuzeigen. Doch leider steht nirgends im Handbuch, daß sich diese Befehle nur auf die normalen ST-Grafikmodi beschränken, da ein BASIC-String nur maximal 32768 Byte aufnehmen kann, was der monochromen Maximal-Pixel-Auflösung von 640 * 400 entspricht. Wird ein Großbildschirm verwendet, bei dem der Bildschirmspeicher größer als 32 KByte angelegt ist, stürzt das Programm garantiert an dieser Stelle ab.

Ein weiteres Problem stellt die Verwendung des Befehls CLS dar, mit dem der gesamte Bildschirminhalt gelöscht werden kann. Sie sollten in Ihren eigenen Programmen immer damit rechnen, daß weitere Programme oder Accessories ebenfalls Bildschirmausgaben machen und diese dann durch das Fehlverhalten Ihres Programmes übermalt werden. Öffnen Sie deshalb für jede Ausgabe ein AES-Fenster. Nur so ist gewährleistet, daß andere Programme „parallel“ zu Ihrem auf dem Bildschirm ausgeben können. Auch der Aufruf der VDI-Funktion v_enter_cur (VDI5, ESC 3) verursacht ein Löschen des gesamten Bildschirminhaltes und sollte deshalb nie benutzt werden.

Warnungen

Vermeiden Sie generell den Einsatz der XBIOS-Funktionen zur Ermittlung oder Beeinflussung der Video-Hardware! Im einzelnen sind dies die Funktionen:

EgetPalette (XBIOS 85)
EgetShift (XBIOS 81)
EsetBank (XBIOS 82)
EsetColor (XBIOS 83)
EsetGray (XBIOS 86)
EsetPalette (XBIOS 84)
EsetShift (XBIOS 80)
Esetsmear (XBIOS 87)
Getrez (XBIOS 4)
Logbase (XBIOS 3)
Physbase (XBIOS 2)
Setcolor (XBIOS 7)
Setpalette (XBIOS 6)
Setscreen (XBIOS 33)

Multitasking

Bereits seit einiger Zeit existiert MultiGEM, ein GEM-Multitasking-System, das es ermöglicht, mehrere Programme nicht nur gleichzeitig im Speicher zu halten, sondern auch „parallel“ ablaufen zu lassen. Damit alles einwandfrei funktionieren kann, müssen sich die Programme strikt an die GEM-Konventionen halten. Einige Programmierer tun dies, aus Programmierzeitgründen nicht andere aus Geschwindigkeitsgründen. Das Betriebssystem ist nun mal nicht das schnellste, aber dafür geräteunabhängig (Grafiktreiber usw.). Damit mehrere Programme gleichzeitig ablaufen können, muß jedes Programm bei Text- oder Grafikausgaben ein AES-Fenster öffnen. Denn nur so ist gewährleistet, daß jedes Programm in einen speziell angeforderten Bildschirmbereich ausgibt. Geschieht dies nicht, wie z.B. bei vielen Zeichenprogrammen zu beobachten, ist es auch nicht möglich, diese Programme parallel ablaufen zu lassen.

Ein weiterer zu beachtender Punkt ist die Gewährleistung, daß mehrere Programme gleichzeitig ablaufen können. Dies ist dann nicht der Fall, wenn eine Dialogbox auf dem Bildschirm angezeigt wird, wenn man sich mit der Maus innerhalb der Menüleiste befinden, und wenn Programme (z.B. Mandelbrotprogramme) die ganze CPU-Zeit an sich ziehen. Ersteres ist sehr häufig bei Programmen zu beobachten, die eine Druckerausgabe erlauben und währenddessen durch einen Dialog darauf hinweisen, daß jetzt nicht mehr weitergearbeitet werden kann.

Nach soviel Hinweisen, Geboten und Verboten sollten Sie jetzt einmal Ihre eigenen Programme durchsuchen. Sie werden sicher die ein oder andere fehlerhafte Stelle finden.

Literatur:

ATARI Profibuch ST-STE-TT, Jankowski/Rabich/Reschke, SYBEX-Verlag

    int	work_in[12], 
		work_out[57];

	int	handle,
		phys_handle;
	
	int gl_hchar, 
    gl_wchar, gl_hbox, gl_wbox;
    int gl_apid;
    int xres,yres;

    /*************************************************/
    /*   boolean open_vwork(void);                   */
    /*                                               */
    /*   Workstation öffnen …                        */
    /*                                               */
    /*   Eingabe:    Nichts                          */
    /*                                               */
    /*   Rückgabe:  TRUE falls das VDI initialisiert */
    /*              werden konnte                    */
    /*              FALSE sonst                      */
    /*************************************************/

    boolean open_vwork(void)
    {
    register int i;

    if((gl_apid = appl_init ( )) != -1)
        {
        for( i = 1; i < 10; work_in[i++] =1);

        /* Koordinatenangaben in Rasterkoordinaten */
        work_in[10] =2;
        /* das AES-Handle für VDI-Aufrufe ermitteln */
        phys_handle = graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
        /* der Funktion muß ein bereits existierendes Handle übergeben werden */
        work_in[0] = handle = phys_handle;
        /* Funktionsaufruf */
        v_opnvwk( work_in, &handle, work_out);
        /* Werte werden im work_out-Array abgelegt */

        xres = work_out[0]; /* Maximalen Pixelwerte */ 
        yres = work_out[1];

        if(handle)
            return (TRUE);
        }

    return (FALSE);
    }

Listing 4: Beispiel zum work_out- und work_in-Feld

WORK_OUT( 0) -	horizontale Pixel-Anzahl
WORK_OUT( 1) -	vertikale Pixel-Anzahl	
WORK_OUT( 2) -	Gerätekoordinaten-Flag  
	0: Bild kann genau skaliert werden  
	1: Bild kann nicht genau skaliert werden		
WORK_OUT( 3) -	Breite eines Pixels in gm (mm/1000)		
WORK_OUT( 4) -	Höhe eines Pixels in gm (mm/1000)
WORK_OUT( 5) -	Anzahl der Schriftzeichenhöhen 0: beliebig veränderbar
WORK_OUT( 6) -	Anzahl der Linientypen
WORK_OUT( 7) -	Anzahl der Linienbreiten 
	0: beliebig veränderbar	
WORK_OUT( 8) -	Anzahl der Marker-Typen		
WORK_OUT( 9) -	Anzahl der Marker-Größen 0: beliebig veränderbar		
WORK_OUT(10) -	Anzahl der verfügbaren Zeichensätze	
WORK_OUT(11) -	Anzahl der verfügbaren Füllmuster	
WORK_OUT(12) -	Anzahl der Schraffuren
WORK_OUT(13) -	Anzahl der vordefinierten Farben		
WORK_OUT(14) -	Anzahl der Grafikgrundfunktionen
WORK OUT(15)bis	
WORK_OUT(24) -	Liste der unterstützten Grafikgrundfunktionen.
	Das Ende ist durch -1 gekennzeichnet. 
	GEM-VDI unterstützt folgende 10 Funktionen: 
	1: Balken 
	2: Bogen
	3: Kreisausschnitt
	4: Kreis
	5: Ellipse
	6: elliptische Bogen
	7: Ellipsensegment
	8: Rechteck mit abgerund. Ecken
	9: ausgefülltes, abgerund. Rechteck
	10: justierter Grafiktext

WORK OUT(25) bis WORK_OUT(34) -	Liste möglicher Attribute für die Grafikgrundfunktionen: 
	0: Linie
	1: Marker
	2: Text 
	3: ausgefüllter Bereich
	4: kein Attribut

WORK_OUT(35) -	Farbdarstellungs-Flag
	0: nicht verfügbar
	1: verfügbar
	
WORK_OUT(36) -	Textrotations-Flag
	0: nicht verfügbar
	1: verfügbar
WORK_OUT(37) -	Flächenfüllung 
	0: nicht verfügbar
	1: verfügbar
WORK_OUT(38) -	CELLARRAY-Flag
	0: nicht verfügbar	
	1: verfügbar
WORK_OUT(39) -	Anzahl der verfügbaren Farben
	0: mehr als 32768
WORK_OUT(40) -	Kennzeichnung für Grafik-Cursor-Kontrolle		
	0: keine	
	1: nur Tastatur	
	2: Tastatur und anderes Gerät (Maus)
WORK_OUT(41) -	Eingabegerät für variierende Eingaben
	0: keine	
	1: Tastatur	
	2: anderes Gerät	
WORK_OUT(42) -	Auswahltasten	
	0: keine	
	1: Funktionstasten auf der Tastatur	
	2: anderes Tastenfeld	
WORK_OUT(43) -	alphanumerische Eingabe (String)	
	0: keine 
	1: Tastatur
WORK_OUT(44) -	Ein-/Ausgabegerät-Typ
	0: nur Ausgabe
	1: nur Eingabe
	2: Ein-/Ausgabe
	3: reserviert
	4: Metafile-Ausgabe
WORK_OUT(45) -	geringste Zeichenbreite
WORK_OUT(46) -	geringste Zeichenhöhe (Abstand zwischen Baseline und Topline)
WORK_OUT(47) -	größte Zeichenbreite  
WORK_OUT(48) -	größte Zeichenhöhe  
WORK_OUT(49) -	geringste Linienbreite  
WORK_OUT(50) -	immer 0  
WORK_OUT(51) -	größte Linienbreite  
WORK_OUT(52) -	immer 0  
WORK_OUT(53) -	geringste Marker-Breite  
WORK_OUT(54) -	geringste Marker-Höhe  
WORK_OUT(55) -	größte Marker-Breite  
WORK_OUT(56) -	größte Marker-Höhe

Tab. 1: Inhalt des work_out-Arrays auf Aufruf der Funktion OPEN WORKSTATION (VDII) oder OPEN VIRTUAL SCREEN WORKSTATION (VDI100)

WORK_OUT(0) -	Bildschirmtyp		
	0: kein Bildschirm
	1: getrennter Alpha- und Grafik-Kontroller und getrennte Bildschirme
	2: getrennter Alpha- und Grafik-Kontroller mit gemeinsamem Bildschirm
	3: gemeinsamer Alpha- und Grafik-Kontroller mit getrenntem Bildschirm
	4: gemeinsamer Alpha- und Grafik-Kontroller mit gemeinsamem Bildschirm
WORK_OUT(1) - Anzahl der verfügbaren Hintergrundfarben
WORK_OUT(2) - Bit-Vektor d.verfügbaren Texteffekte	
WORK_OUT(3) - Flag für Vergrößerungsraster		
	0: Vergrößern möglich	
	1: Vergrößern nicht möglich	
WORK_OUT(4) -	Anzahl der Farbebenen
WORK_OUT(5) -	„Lookup-table“-Unterstützung
	0: nicht verfügbar
	1: verfügbar
WORK_OUT(6) -	Anzahl der 16*16 Pixel-Raster-Operationen pro Sekunde
WORK_OUT(7) -	Contour-Fill-Verfügbarkeit
	0: nicht verfügbar
	1: verfügbar
WORK_OUT(8) -	Textrotation	
	0: nicht möglich
	1: 90°-Drehung
	2: beliebig
WORK_OUT(9) -	Anzahl der Schreibmodi
WORK_OUT(10) -	höchster Grad der Eingabemodi
	0: keiner
	1: request
	2: sample
WORK_OUT(11)-	Textausrichtungsverfügbarkeit
	0: nicht verfügbar
	1: verfügbar
WORK_OUT(12) -	Farbstiftwechsel am Ausgabegerät
	0: nicht möglich
	1: möglich
WORK_OUT(13) -	Farbbandwechselmöglichkeit
	0: nicht verfügbar
	1: farbige Zeilen
	2: farbige Zeilen und Rechtecke
WORK_OUT(14) -	maximale Anzahl von Koordinatenpaaren für Polyline, Polymarker und Filled-Area
	-1: unbegrenzt
WORK_OUT(15) -	maximale Größe des INTIN-Arrays
	-1: unbegrenzt
WORK_OUT(16) -	Anzahl der Maustasten
WORK_OUT(17) -	Linientypen für breite Linien
	0: nicht möglich
	1: möglich
WORK_OUT(18) -	Schreibmodi für breite Linien
	0: nicht verfügbar
	1: verfügbar
WORK_OUT(19) bis WORK_OUT(44) -	reserviert, enthält 0 als Ausgabewert
WORK_OUT(45) -	obere linke x-Koordinate des Clipping Rechtecks
WORK_OUT(46) -	obere linke y-Koordinate des Clipping Rechtecks
WORK_OUT(47) -	untere rechte x-Koordinate des Clipping Rechtecks
WORK_OUT(48) -	untere rechte y-Koordinate des Clipping Rechtecks
WORK_OUT(49) bis WORK_OUT(56) -	reserviert, enthält 0 als Ausgabewert.

Tab. 2: Inhalt des work_out-Arrays nach Aufruf der Funktion EXTENDED INQUIRE FUNCTION (VDI 102)


Jürgen Haage
Aus: ST-Computer SH / 1992, Seite 19

Links

Copyright-Bestimmungen: siehe Über diese Seite