TOS: fix gefixed

In allen TOS-Versionen ist, wie sich kürzlich herausstellte, die vr_trnfm()-Routine fehlerhaft. Unser Programm behebt den Fehler.

In unserer Juli-Ausgabe stellten wir ein Programm vor, das intensiv Gebrauch von der VDI-Funktion »vr_trnfm()« macht [1]. Erinnern wir uns: Bit-Blöcke, die GEM in den Bildschirmspeicher oder aus ihm heraus kopiert, müssen im internen Format des Bildschirmtreibers vorliegen. über dieses Format sollte kein Programm irgendwelche Annahmen machen. Zwar hat Atari den Aufbau des ST-Bildschirmspeichers bereits frühzeitig dokumentiert, jedoch ist mittlerweile eine Vielfalt von Grafikkarten erhältlich, die vollkommen anders aufgebaute Speicherkonstruktionen verwenden. Damit ein Programm also auch auf diesen Karten reibungslos funktioniert, darf kein Programmierer von irgendeinem Format des Bildschirmspeichers ausgehen. Das ist zumeist auch gar nicht nötig: Oftmals muß ein Programm nur einen Bildschirmausschnitt puffern oder verschieben - zu verändern braucht es ihn nicht. Nun gilt es aber, VDI zur Ausgabe zu benutzen.

Ein Beispiel hierfür sind einige Programme, z. B. Bit-Block-Kopierfunktion von Terminalprogrammen und Textverarbeitungen, denen die VDI-eigene Textausgabefunktion »v_gtext()« zu langsam arbeitet. Sie kopieren größere Speicherblöcke mit »vro_cpyfm()« oder »vrt_cpyfm()« direkt in den Bildschirmspeicher. Doch jetzt stellt sich folgendes Problem: Woher sollen die Programme wissen, wie der Bildschirmspeicher aufgebaut ist? Schlechte Programme ignorieren dieses Problem einfach: Das Resultat ist lebenslange Inkompatibilität mit allen aufwendigeren Grafikkarten.

Intelligente Programme hingegen legen ihre Bit-Blöcke zunächst in einem internen Format ab, dem VDI-Standardformat. Das VDI-Standardformat ist auf allen GEM-Systemen und -Grafikkarten gleich [2]. Es zerlegt einen Bit-Block in hintereinander liegende Einzelblöcke jeder Farbplane. Die Konvertierung vom gerätespezifischen ins Standardformat übernimmt wiederum eine VDI-Funktion, »vr_trnfm()«. Jeder Bildschirmtreiber implementiert sie anders, und somit funktioniert sie auf allen Grafikkarten wie gewünscht.

Davon lebt beispielsweise die »VDI-Lupe«: Jeder Bildschirmblock wird ins Standardformat konvertiert, dann auf Word-Ebene von unserem Programm vergrößert, das Resultat zurücktransformiert und auf den Bildschirm kopiert. Mittlerweile existiert ein zweites Programm, das ähnlich arbeitet: die »AES-Lupe«, über dessen Vertriebsweg noch nicht entschieden ist.

Die AES-Lupe tätigt alle Ausgaben in einem Fenster, dessen Größe der Anwender festlegt. So kommt es, daß das Lupenfenster schon mal eine Größe von 1280 x 960 Punkten annimmt, nämlich auf Großbildschirmen und unter "Bigscreen,c [31. Und hier zeigte sich Merkwürdiges: Sobald das Lupenfenster eine bestimmte Größe über-

schritt, erschien im Fenster nur noch Pixel-Müll. Nachdem wir zunächst auf einen Speicherfehler tippten und dann den Fehler in unserer Vergrößerungsroutine zu orten hofften, stellte sich zuletzt heraus, daß die TOS-Routine »vr_trnfm()« schlicht fehlerhaft arbeitet. »vr_trnfm()« benutzt, wie sich beim Disassemblieren der TOS-Routine zeigte, intern einen in der Transform-Schleife mitlaufenden Offset auf die gerade transformierten Speicherzellen. Dieser Offset wird über eine »dbra«-Schleife dekrementiert. Der 680x0-Befehl »dbra« arbeitet jedoch grundsätzlich nur auf Word-Breite, also mit 16 Bit Genauigkeit. Das führte dazu, daß große Teile des Bit-Blocks nicht transformiert wurden, wenn der Offset-Zähler die 16-Bit-Grenze überschritt. Das ist genau dann der Fall, wenn im »MFDB« (»Memory Form Definition Block«) des transformierten Bit-Blocks

fd_h * fd_wdwidth > 65535 

ist. Bei unserer Autopsie stellte sich heraus, daß Atari den Fehler offenbar irgendwann einmal bemerkt hat: In den TT-TOS-Versionen tritt der Fehler nur noch auf, wenn ein Block in sich selbst, also in seinen eigenen Speicherbereich transformiert wird. Dies ist aber sehr selten, weil eine Konvertierung in den eigenen Speicherblock sehr langsam vonstatten geht, weshalb es die meisten Programmierer bleiben lassen. Wir haben Atari diesen Fehler gemeldet, eine Stellungnahme aus Sunnyvale steht aber noch aus. Denselben Fehler zeigte auch der Screenspeeder »NVDI«, dessen Version 1.04 dieses Manko jedoch nicht mehr aufweist. In Zusammenarbeit mit den Programmierern von »NVDI« entstand der »vr_trnfm()-Fix«, den wir in dieser Ausgabe vorstellen.

Unser Fixprogramm enthält eine komplette neue »vr_trnfm()«-Routine, welche die des Atari-Bildschirmtreibers ersetzt. Sie stammt aus dem fehlerbereinigten »NVDI« und ist in reinem Assembler-Code geschrieben. Daher arbeitet sie auch noch um ein Vielfaches schneller als Ataris Funktion.

Die Installation ist recht einfach: Kopieren Sie den Fix einfach in ihren Autoordner. Wenn Sie eine Grafikkarte mit eigenem Treiber verwenden, benötigen Sie ihn natürlich nicht. Unser Fixprogramm hängt sich in den VDI-Trap. Dort wartet es zunächst einmal auf »vr_trnfm()«-Aufrufe, die über die XBRA-Kette herangetragen werden. Liegt kein »vr_trnfm()«-Aufruf vor, dann durchspringt das Programm die XBRA-Kette wie gewohnt.

Im Falle eines »vr_trnfm()«-Calls wird die »NVDI«-Funktion aktiv und transformiert anstelle des Atari-VDI. Eine Sonderbehandlung erfährt ein undokumentierter Systemaufruf, der gemeinhin »vq_driver()« genannt wird. Er ist weder ein AES- noch ein VDI-Aufruf und steht damit etwas abseits. Der Aufruf liegt dann vor, wenn beim Ansprung des Trap #$02 im Datenregister D0 der Wert -1 steht. Alle VDI-Treiber liefern daraufhin einen Zeiger auf ihre interne Treiberroutine, die beispielsweise von allen GDOS-Programmen (GDOS, AMCGDOS, G+PLUS, FONTGDOS, FSMGDOS) per »jsr« angesprungen wird. Damit »überspringt« GDOS die XBRA-Kette im Trap # $02. Um dennoch auch unter GDOS arbeiten zu können, erfragt unser Fix am Programmstart die echte VDI-Einsprungadresse per »vq_driver()« und speichert sie. Wenn irgendein später gestartetes Programm nun einen »vq_driver()«-Aufruf tätigt, bekommt es daraufhin nicht etwa die echte VDI-Adresse geliefert, sondern einen Zeiger auf einen zweiten Dispatcher unseres Fixprogramms, der seinerseits bei jedem Durchsprung entscheidet, ob er der Call ans VDI weiterleitet, oder von der internen »vr_trnfm()«-Routine bearbeiten läßt.

Prinzipbedingt kann ein Programm wie »NVDI« mit unserem Fixprogramm nicht fehlerbereinigt werden. Das ist aber auch gar nicht nötig, denn jeder Käufer von »NVDI« kann sich problemlos ein Update auf die Version 1.04 besorgen. Dennoch macht der Fix im Zusammenspiel mit »NVDI« Sinn: In den Farbauflösungen bleibt »NVDI« inaktiv, solange die Farbversion noch in Vorbereitung ist. Während eine »NVDI«-Version > = 1.04 in den Monochromauflösungen den Fehler behebt, geschieht dies in einer Farbauflösung nicht. Deshalb sollten Sie den »vr_trnfm()«-Fix vor »NVDI« in den AUTO-Ordner kopieren. So gestartet, hängt »NVDI« den Fix in den Monochromauflösungen aus und beim Wechsel in eine Farbauflösung wieder ein. Um sicherzustellen, daß der Fix im AUTO-Ordner vor »NVDI« gestartet wurde, prüft unser Programm den »NVDI«-Cookie: Ist er bereits vorhanden, liegt NVDI schon im System.

Nicht zu übersehen, daß gerade ein TOS-Fixprogramm immer eine wacklige Sache ist: Ein fehlerbereinigtes TOS wäre uns lieber (und das wird, da sind wir sicher, auch kommen). Dennoch hilft der Fix den gröbsten Problemen fürs erste ab. Wir sind für Kommentare oder Verbesserungsvorschläge jeder Art immer empfänglich. Also zögern Sie nicht: schreiben Sie uns.

(uw)

Literatur:

[1] L. Prüßner, »Es gibt sie doch -die saubere Lupe«, ST-Magazin 7/91, Seiten 58f., Markt & Technik Verlag.

[2] »GEM Programmer's Guide, Volume 1: VDI, 3rd Edition« Atari Corp. Sunnyvale 1989.

[3] J. Reschke, »Ein Haufen Vermischtes«, ST-Magazin 7/91, Seiten 60ff., Markt & Technik Verlag.

Listing: Reparatur per Patch: vr_trnfm()-Routine


Laurenz Prüßner
Aus: ST-Magazin 09 / 1991, Seite

Links

Copyright-Bestimmungen: siehe Über diese Seite