★ APPLICATIONS ★ DIVERS ★ Was Sie schon immer über Hardcopies wissen wollten ★![]() |
| Hardcopyprogramm (CPC Amstrad International) | Applications Divers |
Wie man Hardcopies auf dem CPC selber programmiert Sieht man sich die Leserbriefecke der “PC Amstrad International“ einmal näher an, so stellt man fest, daß kaum ein Thema die Gemüter so erhitzt wie die Druckeranpassung für diverse Hardcopyprogramme. Dieser Beitrag soll Ihnen zeigen, was Hardcopyprogramme sind, wie sie funktionieren und wie man diese selbst programmieren kann. Hier kommen sowohl BASIC-als auch Maschinenspracheprogrammierer auf ihre Kosten: Zuerst werden wir ein Hardcopyprogramm in BASIC und dann eines in Maschinensprache schreiben. Zunächst sollte geklärt werden, was Hardcopyprogramme sind. Es sind Programme, die den Bildschirminhalt möglichst maßstabsgetreu auf dem Drucker ausdrucken. Das “möglichst“ sollte betont werden, da wohl die wenigsten Leute einen Plotter oder Farbdrucker ihr eigen nennen. Wir wollen uns deshalb auf neunnadlige EPSON-und kompatible Matrixdrucker beschränken, da EPSON quasi Standard in der Druckerbranche ist, und neunnadiige Drucker immer noch den Großteil der im Homecomputerbereich benutzten Drucker ausmachen. Trotzdem sind Anpassungen an andere Druckertypen leicht möglich, da alles genau beschrieben wird. Der Druckkopf Bevor wir allerdings so richtig loslegen, sollten wir uns mit der Hardware des Druckers beschäftigen. Schauen Sie sich bitte einmal Abbildung 1 an. Sie zeigt schematisch die Darstellung eines neunnadligen Druckkopfes. Es fallt sofort auf, daß die neunte Nadel nicht benutzt wird. Sie wird nur bei der sogenannten 9-Nadel-Grafik angesprochen, die wir hier aber außer acht lassen. Die Abbildung zeigt, daß sich jede Nadel durch eine Zweierpotenz ansprechen läßt. Wenn Sie zum Beispiel die Nadeln 2, 5 und 7 aktivieren wollen, müssen Sie einfach die Werte 26, 21 und 21 addieren und diesen Wert dann dem Drucker mit PRINT # 8,CHR$(74)Übermitteln.Das leidige achte Bit Das ist allerdings gar nicht so einfach, weil uns die Hardware des CPCs einen Strich durch die Rechnung macht. Die Druckerschnittstelle des CPCs spricht nämlich bei der Übermittlung von Daten das achte Bit nicht an. Das heißt, daß wir nur Zeichen von 0 bis 127 übermitteln können und daß uns deshalb nur maximal 7 Nadeln zur Verfügung stehen. Leider kann ich Ihnen nicht sagen, warum die Firma AMSTRAD auf dieses wichtige achte Bit verzichtet hat. Aber auch dieses Manko läßt sich überwinden, wie Sie später sehen werden. Der Einfachheit halber werden wir das Hardcopyprogramm für den MODE 2 schreiben, da sich Farben, wie sie in MODE 1 und MODE 0 existieren, auf einem “normalen“ Matrixdrucker nur durch verschiedene Muster andeuten lassen, und das würde die Sache unnötig komplizierter machen. MODE 2 hat, wie Sie wissen, horizontal 640 und vertikal 200 Bildpunkte (intern rechnet der Computer aber mit 400 vertikalen Bildpunkten, bei der Darstellung wird aber jeder zweite übersprungen). Wir benötigen also ein Programm, das, von links oben beginnend, immer sieben untereinanderliegende Punkte in eine Bytezahl umwandelt (wie vorher beschrieben), zum Drucker sendet und nach rechts das ganze 640mal wiederholt. Dann sollte das Programm mit der nächsten Zeile beginnen.
Dieser Vorgang muß insgesamt 29mal wiederholt werden, da Sie ja die vertikalen 200 Punkte in je 7 Punkte aufteilen müssen. Da die überschüssigen 3 Punkte (29 mal 7 gibt 203) wegfallen, besteht die letzte und 29. Zeile nur aus vier übereinanderliegenden Punkten. Machen Sie sich diesen Sachverhalt bitte an Abbildung 2 deutlich. Wenn Sie das bis hierher Besprochene in ein Programm umsetzen und dieses dann starten, wird der Drucker statt der erhofften Grafikzeichen Textzeichen ausdrucken. Was haben Sie falsch gemacht? — Richtig, Sie müssen den Drucker erst auf Grafikdruck umprogrammieren, und das ist gar nicht so einfach. Die Steuercodes Wenn Sie sich schon des öfteren mit Ihrem Drucker beschäftigt haben, dann kennen Sie sicher die sogenannten ESCAPE-Sequenzen. Das sind Steuerbefehle, die mit dem ASCII-Zeichen 27 beginnen, dem wiederum ein bestimmter Code nachfolgt. Damit können Sie den Drucker zum Beispiel auf Kursiv-, Fett- und Grafikdruck umstellen. Hier haben Sie sogar verschiedene Auflösungen zur Auswahl: je nach Drucker 60, 120 oder 240 Punkte pro Zoll. Da horizontal 640 Punkte dargestellt werden sollen, wird die Auflösung von 120 Punkten pro Zoll benötigt, damit die Hardcopy auch auf ein normales DIN-A4-Blatt paßt. Diese Auflösung stellt man bei EPSON- und kompatiblen Druckern mit folgendem Befehl ein: PRINT # 8,CHR$(27)+“L“ + CHR $(a1)+ CHR$(a2)Mit den Werten al und a2 wird angegeben, wie viele Punkte horizontal ausgegeben werden. Die Variable al gibt das Lowbyte und die Variable a2 das Highbyte der horizontalen Punkteauflösung an. In unserem Fall wäre das die Zahl 640, die wir in Low- und Highbyte zerlegen müßten. Für Leute, die sich mit dem Low- und Highbyte noch nicht so richtig auskennen, folgende Erklärung: Das Highbyte ist der ganzzahlige Quotient einer Zahl und das Lowbyte der Rest. In BASIC sähe unsere Berechnung folgendermaßen aus:a2=INT(640/256):a1=640-256*a2Wir bekommen also für al die Zahl 128 und für a2 die Zahl 2 heraus. Doch zurück zu den Steuerbefehlen. Die Umschaltung auf Grafikdruck sähe in unserem Fall also folgendermaßen aus:PRINT# 8,CHR$(27) +'‘L“+CHR$(128)+CHR$(2)Damit würden wir allerdings beim CPC ins Fettnäpfchen treten, ganz einfach, weil wir voher gelernt haben, daß der CPC durch das Fehlen des achten Schnittstellenbits dem Drucker nur Zeichen von 0 bis 127 übermitteln kann. Deshalb würden wir mit dem “CHR$(128)‘‘ Schiffbruch erleiden.
'Was tun?' fragte der Programmierer Die Lösung dieses Problems besteht darin, den Wert der horizontalen Auflösung (bisher 640) so zu erhöhen, daß sowohl Low- als auch Highbyte unter dem Limit von 128 liegen. Nach längerem Probieren kommt man auf die nächsthöhere Zahl, bei der das der Fall ist, nämlich 768. Bei ihr ist das Lowbyte 0 und das Highbyte 3. Unsere Umschaltung auf den Grafikdruck lautet folglich: PRIINT #8 , CHR$(27)+ "L" + CHR$(0)+CHR$[3)Sie werden sich jetzt natürlich fragen, was wir mit den 128 (768 weniger 640 gibt 128) überflüssigen Grafikzeichen machen, denn die vom Hardcopyprogramm abgeschickten Daten müssen der Zahl 768 genau entsprechen, weil es sonst zu merkwürdigen Ergebnissen kommen könnte. Aber auch hierfür gibt es eine Lösung: Wir senden dem Drucker zuerst 128 Nullbytes und dann die 640 Grafikzeichen. So rückt die Hardcopy etwas in die Mitte des Papiers, und es kommt zu keinen unliebsamen Ergebnissen.Das BASIC-Programm Listing 1 ist ein solches Hardcopyprogramm - und zwar in BASIC geschrieben: Das “WIDTH 255“ in Zeile 30 dient dazu, den automatischen Wagenrücklauf und Zeilenvorschub auszuschalten. BASIC hat nämlich die Eigenschaft, standardmäßig nach je 132 Zeichen den Drucker zu veranlassen, einen Zeilenvorschub (ASCII-Code: 10) und einen Wagenrücklauf (ASCII-Code: 13) zu machen. Da wir dies aber nur nach je 768 Zeichen haben wollen, hätte das unliebsame Auswirkungen. Mit dem “ORIGIN 0,0“ wird das Grafiksystem des CPC zurückgesetzt. Zeile 40 schaltet mit einem Steuercode den Zeilenvorschub auf 7/72 Zoll. Damit wird sichergestellt, daß keine Abstände zwischen den Druckzeilen entstehen. Die Variable y wird in Zeile 50 mit der ersten Bildschirmzeile geladen. In Zeile 60 tritt der CPC in eine FOR-NEXT-Schleife ein, die ihn veranlaßt, die Zeilen 70 bis 150 29mal zu wiederholen. Zeile 70 bringt den Druckkopf in die nächste Zeile, und Zeile 80 stellt den Drucker auf Grafikdruck mit 768 horizontalen Punkten ein. Jetzt müssen dem Drucker 768 Daten für eine Zeile übergeben werden: Zeile 90 schickt an den Drucker zunächst 128 Nullbytes, damit dieses Soll erfüllt wird. Jetzt werden mit der Schleife in Zeile 100 alle horizontalen Punkte auf dem Bildschirm abgefragt. Das erledigt die BASIC-Funktion TEST in Zeile 110. Diese Funktion bewegt den Grafikcursor an den angegebenen Koordinatenpunkt und gibt die Nummer des Farbstifts an, der an dieser Position verwendet wurde. ,In MODE 2 sind nur zwei Werte möglich, nämlich 0 und 1. Zeile 110 prüft nun die sieben untereinanderliegenden Punkte, indem sie die Nummer des Farbstifts mit der jeweiligen Zweierpotenz multipliziert und die Werte dann addiert. Dieser Vorgang wird Ihnen wahrscheinlich verständlicher, wenn Sie sich Abbildung I noch einmal anschauen. Zeile 120 prüft, ob das Programm gerade die letzte Zeile geprüft hat. Ist das der Fall, so werden mit der AND-Funktion nur die Bits 3 bis 6 zugelassen, da die letzte Zeile nur aus vier Grafikzeilen besteht. Abbildung 2 macht Ihnen diesen Vorgang verständlicher. Zeile 130 druckt dann endlich das Grafikzeichen aus. Wichtig ist hier vor allem, wie bei allen anderen PRINT #8-Kommandos, daß am Schluß das Semikolon nicht vergessen wird, da der Druckkopf sonst gleich in die nächste Zeile springen würde. Mit der Zeile 140 wird dann sofort die nächste x-Koordinate bearbeitet. Sobald das Programm mit einer Druckzeile fertig ist, wird die y-Koordinate in Zeile 150 um 7 Pixel vermindert, und der Vorgang beginnt von neuem, bis alle 29 Druckzeilen abgearbeitet sind. Wenn Sie das Programm wie abgedruckt starten, werden Sie feststellen, daß es zwar funktioniert, den Druckvorgang aber in einer äußerst langsamen Geschwindigkeit bewerkstelligt. Für eine Hardcopy braucht dieses Programm auf meinem Drucker durchschnittlich 12 Minuten! Vor allem die TEST-Funktion in Zeile 110 nimmt viel Zeit in Anspruch. Sie wissen wahrscheinlich schon, auf was ich hinaus will: Eine Programmierung des Hardcopyprogramms in Maschinensprache wird unumgänglich, Wenn Ihnen das BASIC-Programm aber klar ist, wird Ihnen dieser Schritt auch nicht mehr schwerfallen.
Last, but not least: das Eine Umsetzung des BASIC-Programms in Maschinensprache ist Listing 2. Es entspricht im großen und ganzen dem vorher besprochenen Hardcopyprogramm, ist aber wesentlich schneller. Zeile 40 rettet zunächst einmal den Stack-Pointer. Wenn das Hardcopyprogramm später wieder ins BASIC zurückkehrt (Zeile 780), wird dieser Stack-Pointer zurückgeholt. Mit dem “CALL &BBBA“ in Zeile 50 wird das Grafiksystem sicherheitshalber zurückgesetzt, damit es später nicht zu Unannehmlichkeiten kommt. Die Zeilen 60 bis 240 stellen den Drucker auf Grafikdruck und den richtigen Papiervorschub ein. Außerdem wird das HL-Register mit der y-Koordinate geladen (Zeile 100). Das B-Register dient als Zählregister für die 29 Druckzeilen (Zeile 110). Das Unterprogramm “druck“ ab Zeile 590 sendet übrigens das Zeichen, welches im A-Register übergeben wird, zum Drucker. Zunächst wird geprüft, ob die ESC-Taste gedrückt wurde (600-620). Ist das der Fall, springt das Programm sofort unverrichteter Dinge ins BASIC zurück.
Andernfalls wird getestet, ob der Drucker zur Ausgabe des Zeichens bereit ist. Ist dem nicht so, wird der ganze Vorgang wiederholt. Ansonsten wird das Zeichen ausgegeben und zum Hauptprogramm zurückgekehrt (Zeile 660). Danach gibt der Drucker in den Zeilen 250 bis 280 die 128 Leerzeichen aus. Die nun folgenden Zeilen 300 bis 530 werden nun 640mal wiederholt. Sie wandeln die Bildpunkte auf dem Bildschirm in Grafikzeichen um, die dann zum Drucker geschickt werden. Besonders die Zeilen 300 bis 370 sind wichtig: Sie entsprechen der Zeile 110 im BASIC-Hardcopyprogramm. Zuerst wird das Unterprogramm “test" aufgerufen. Dieser Programmteil prüft das Vorhandensein eines Punktes an bestimmten Koordinatenpunkten. Wenn ein Punkt vorhanden ist, so ist das Carry-Flag gesetzt, ansonsten ist es zurückgesetzt. Zeile 340 schiebt nun den Wert des Carry-Flags links in das C-Register. Das gleiche geschieht nun mit den darunterliegenden Bildpunkten. Somit hat das C-Register am Schluß den Wert des auszugebenden Zeichens. Dieses “Schieben“ nach links innerhalb eines Registers entspricht übrigens immer einer Multiplikation mit einer bestimmten Zweierpotenz. Abbildung 4 veranschaulicht Ihnen die Funktionsweise des RLC-Befehls. Somit sind die Zeilen 330 bis 370 im MC-Programm analog zu Zeile 110 im BASIC-Programm. Bevor das Zeichen zum Drucker geschickt wird, folgt die Auswahl der ersten vier Pixel, sofern die letzte Druckzeile gerade bearbeitet wird (Zeile 450). Ist das Programm mit einer Druckzeile fertig, springt es in die nächste Druckzeile, indem von der y-Koordinate 7 Pixel abgezogen werden (Zeilen 540 und 550). Wenn alle 29 Druckzeilen ausgedruckt worden sind, kehrt das Programm ins BASIC zurück. Obwohl das MC-Programm im großen und ganzen dem BASIC-Programm entspricht, ist es wesentlich schneller: Für eine Hardcopy benötigt es knapp zwei Minuten. Trotzdem könnte es noch um einiges schneller sein, vor allem wenn man für die Abfrage eines Bildpunktes eine schnellere Routine fände. Oder wie wäre es mit der Anpassung dieses MC-Programms an andere Bildschirmmodi? Das alles würde aber den Rahmen dieses Beitrags sprengen. Wenn Sie aber die Funktionsweise der Hardcopyprogramme begriffen haben, dürfte Ihnen die Lösung dieses Problems nicht mehr allzu viele Schwierigkeiten bereiten. Abschließend finden Sie noch eine Zusammenstellung aller benutzten Betriebssystemroutinen und der wichtigsten BASIC- und Maschinensprache-Befehle. Wir hoffen, Ihnen die schwierige Materie “Hardcopies“ nähergebracht zu haben und würden uns freuen, wenn dieses Thema dem Lesepublikum zukünftig weniger Kopfzerbrechen bereiten würde. Wir wünschen Ihnen noch viel Spaß beim Ausdruck Ihrer grafischen Ergüsse! (Markus Felder/cd) , CPCAI 90/03
|