Der Epson-Plotter

Natürlich ist es ein hochgestecktes Ziel, wenn man versucht, einem Matrix-Drucker die Fähigkeiten eines Plotters zu entlocken. Doch mit einer Dichte von über 90 (neunzig) Punkten pro Zentimeter läßt sich schon einiges anfangen.

Eine Hardcopy vom Grafikbildschirm des C 64 ist für den Ausdruck komplizierterer Funktionen oft zu klein und in der Auflösung zu ungenau. Das ändert sich jedoch schlagartig, wenn man die Grafiken nicht vom Bildschirm kopiert, sondern Zeile für Zeile berechnet und sofort ausdruckt. So entsteht aus einer Zeile mit einer Auflösung von 200 Punkten eine Zeile aus bis zu 1920 Punkten entlang der Y-Achse. Da dann die X-Achse in Richtung des Papiervorschubes, also vertikal gelegt ist, bedeutet dies einen nahezu beliebig großen Ausschnitt aus einer Funktion.

Eingabehinweise

Geben Sie zunächst das Maschinenprogramm »PLOTTER MASCH« (Listing 1) mit dem MSE ein und speichern Sie es. Dann tippen Sie das Hauptprogramm »EPSON PLOTTER« (Listing 2) mit dem Checksummer ein und speichern es ebenfalls. Beim Starten dieses Programms wird dann das Maschinenprogramm automatisch nachgeladen.

Programmbeschreibung

Hat man das Programm »Epson Plotter« geladen und gestartet, dann dauert es zunächst ein wenig, bis dann schließlich die Frage: »F(X) = ?«erscheint. Man gibt hierauf die Funktion ein, die man auf dem Drucker dargestellt haben will.

Man kann auch Scharen mit einem Parameter drucken lassen. Dieser Parameter muß »a« lauten, so zum Beispiel: sin(x) oder a*sin(x + a)

Die Eingabe muß in der üblichen Form vorgenommen werden, die der C 64 versteht (siehe Handbuch).

Hat man nun diese Eingabe beendet, wird man anschließend nach Definitions- und Wertebereich gefragt.

Man gibt zunächst die untere Grenze des Definitionsbereichs an, dann, gefolgt von einem Komma, die obere und drückt RETURN. Natürlich muß der untere Wert kleiner sein als der obere.

Genauso verfährt man mit dem Wertebereich. Der Epson-Drucker hat verschiedene Dichten zur Verfügung, in denen er horizontal drucken kann. Das Programm fragt jetzt nach dieser Auflösung. Es druckt dazu auf dem Bildschirm alle möglichen Auflösungen aus und versieht sie mit einer Nummer. Man gibt nun diese Nummer an (0 bis 5), und der Drucker wird nachher in der gewünschten Dichte drucken.

Da jeder Drucker mit Endlospapier in vertikaler Richtung beliebige Längen drucken kann, ist diese Möglichkeit im Programm integriert. Auf die Frage »Breite der X-Achse…« gibt man die Anzahl der Punkte an, die der Drucker vertikal druckt. Das heißt man bestimmt die Länge der X-Achse auf dem Papier.

Hatte man sich bei der Funktionseingabe dazu entschlossen, eine Schar-Funktion drucken zu lassen, so kann man jetzt die notwendigen Schar-Parameter eingeben. Man beantwortet die Frage »…Funktionenschar?« entweder mit »J« oder »N«. Hat man sich für Ja entschieden, so gibt man die Parameter ein.

Will man keinen Parameter mehr angeben, so wird durch die Eingabe »Ende« diese Eingabenserie beendet.

Der Computer ist nun bereit, die zu druckende Funktion in Form von Grafikdaten an den Drucker zu übermitteln. Er beginnt damit, nachdem man eine beliebige Taste gedrückt hat (siehe Bild 1).

Punktgrafik mit mehreren Kurven um zwei senkrechte Achsen und waagerechte Achse
Bild 1. Beispielausdruck einer Funktionsschar mit dem Epson-Plotter

Anmerkungen

Betreibt man seinen Drucker mit einem Software-Interface, dann muß man dabei folgendes beachten. Der Bereich $c000 bis $cfff wird vom »Epson-Plotter« fast vollständig genutzt. Das heißt ein solches Interface darf sich nicht in diesem Bereich befinden. Geeignet ist der Bereich $9000 bis $9fff, wobei dabei auch zu beachten ist, daß man ihn dann gegen Überschreiben durch Variablen schützt (Speicherstelle 55,56).

Wichtig ist auch, daß man ein Interface verwendet, das durch Öffnen des Kanals 4 den Drucker im Epson-Modus anspricht. Ansonsten muß die Zeile 176 entsprechend geändert werden.

Es wird grundsätzlich jede Funktion dargestellt. Auch solche, die an manchen Stellen nicht definiert sind oder gegen unendlich gehen. Der Trick hierbei ist, daß man den Fehlermeldungsvektor (768,769) auf einen RTS-Befehl zeigen läßt. (Nur im Programmodus möglich, sonst Absturz des C 64.) Dies hat zur Folge, daß jegliche Fehlermeldung unterdrückt, die Funktion an dieser Stelle nicht eingezeichnet und mit dem nächsten Funktionswert fortgefahren wird. Das Programm macht sich ferner eine Möglichkeit des Druckers zunutze, die es gestattet, in verschiedenen Matrixpunktdichten zu drucken. Dies bewirkt, daß eine Funktion mit uneingeschränktem Wertebereich noch genauer dargestellt werden kann. (Bei 1920 Punkten können zwei nebeneinanderliegende Punkte nicht gedruckt werden.)

Dadurch, daß man den Definitionsbereich frei wählen kann, wird es möglich, eine Funktion auf eine Länge von weit über 50 cm zu drucken. Das Maschinenprogramm bewirkt, daß bei jeder Auflösung das Ausgeben der Grafikdaten sehr schnell vonstatten geht.

(V. Raum/og)
PROGRAMM : PLOTTER MASCH  C000 C0A8
-----------------------------------
C000 : A5 02 C9 00 D0 06 A9 01   FF
C008 : A2 E0 D0 35 C9 01 D0 06   E9
C010 : A9 03 A2 C0 D0 2B C9 02   8D
C018 : D0 06 A9 03 A2 C0 D0 21   6C
C020 : C9 03 D0 06 A9 07 A2 80   BE
C028 : D0 17 C9 04 D0 06 A9 02   5F
C030 : A2 80 D0 0D C9 06 D0 06   04
C038 : A9 02 A2 D0 D0 03 4C 48   8C
C040 : B2 85 FC 86 FB A2 00 86   A7
C048 : FD A2 C3 86 FE A9 1B 20   42
C050 : D2 FF A9 2A 20 D2 FF A5   B5
C058 : 02 20 D2 FF A5 FB 20 D2   7F
C060 : FF A5 FC 20 D2 FF A0 00   25
C068 : B1 FD 20 D2 FF A6 FD E8   79
C070 : D0 02 E6 FE 86 FD A6 FB   C6
C078 : CA E0 FF D0 02 C6 FC 86   24
C080 : FB E0 00 D0 E1 A6 FC D0   EE
C088 : DD A2 00 86 FB A2 C3 86   78
C090 : FC A0 00 98 91 FB C8 D0   AD
C098 : FB A6 FC E8 E0 CF F0 05   9D
C0A0 : 86 FC 4C 91 C0 60 00 00   F9
Listing 1. Den Maschinenspracheteil »PLOTTER MASCH« geben Sie bitte mit dem MSE ein.
1 rem *********************************
2 rem *                               *
3 rem *         epson plotter         *
4 rem *                               *
5 rem *   c-64 + epson rx 80 (f/t+)   *
6 rem *       (+ interface)           *
7 rem *                               *
8 rem *********************************
9 rem *                               *
10 rem*         volker raum           *
11 rem*     noetherstrasse 20a        *
12 rem*        8520 erlangen          *
13 rem*         09131/65511           *
14 rem*                               *
15 rem*********************************
16 :
17 :
30 rem "{clr} = shift+clr/home
32 rem "{down} = cursor down
34 rem "{lblu} = c= + 7
36 rem "{blu} = ctrl + 7
38 rem "{left} = cursor left
40 ifpeek(49152)<>165thenload"plotter masch",8,1:rem laden druckerausgabe
42 poke53281,6
44 sys49289 :rem loeschen des ausgabepuffers
46 clr
48 print"{clr}{down}{lblu}               plotter "
50 print"{down}         c-64 <-> rx-80 (f/t)"
52 print"{down}   eine bel. funktion f(x) wird auf"
54 print"{down}       dem drucker ausgedruckt."
56 input"{down} f(x) = ";f$:iff$=""then74:rem eingabe der funktion
58 print"{clr}{blu}10000 deffnf(x)=";f$
60 print"10010 f$="chr$(34);f$;chr$(34)
62 print"goto74
64 poke631,19:poke632,13:poke633,13:poke634,13:poke198,4:end
66 rem
68 rem funktion in deffnf einsetzen und f$ zuruecksetzen
70 rem *** programmierter direktmodus ***
72 rem
74 dim sw(200):rem scharparameter
76 gosub 10000:print"{lblu}":rem deffnf ausfuehren
78 print"{clr}{down} f(x) = ";f$
80 print"{down} angabe des definitionsbereiches :"
82 input"{down} xa,xe :   -5,5       {left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}";xa,xe
83 ifxa>xe thenprint"{up}{up}";:goto82
84 input"{down} ya,ye :   -5,5       {left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}";ya,ye
85 ifya>ye thenprint"{up}{up}";:goto84
86 rem definitions und wertebereich von f(x)
88 print"{down} aufloesung y-richtung :"
90 print" 0) 480 einzelpunkte"
92 print" 1) 960 einzelpunkte"
94 print" 2) 960 einzelpunkte doppelte gesch."
96 print" 3) 1920 einzelpunkte "
98 print" 4) 640 einzelpunkte "
100 print" 5) 720 einzelpunkte "
102 input"{down} aufloesung :  0{left}{left}{left}";a1
104 if a1=0thenaf=480
106 if a1=1thenaf=960
108 if a1=2thenaf=960
110 if a1=3thenaf=1920
112 if a1=4thenaf=640
114 if a1=5thenaf=720:a1=6
116 ifa1>5goto102
118 poke2,a1
120 rem
122 rem aufloesung fuer drucker eingeben (y-richtung)
124 rem uebergabe dieser aufloesung an das masch.prog.
126 rem
128 print"{clr}{down} f(x) = "f$
130 print"{down} breite der x-achse auf dem drucker"
132 print"{down} in punkten"
134 input"{down} aufloesung :  480{left}{left}{left}{left}{left}";a2
135 a2=a2-1
136 rem angabe der laenge des ausdrucks a2/8=zeichen
138 input"{clr}{down} ist f(x) eine funktionenschar   n{left}{left}{left}";fs$
140 if fs$="n"then150
142 sc=1:print
144 print" a("sc")= ";:input gf$
146 ifgf$="ende"then150
148 sw(sc)=val(gf$):sc=sc+1:goto144
150 rem falls schar,dann angabe der parameter
152 dy=abs(ye-ya)/af:rem 1punkt=?x
154 dx=abs(xe-xa)/a2:rem schrittweite
156 rem einheiten der x-und y-achse
158 lx=(-ya*af/(ye-ya))
160 ly=int((-xa*a2/(xe-xa))+.5)+1
162 iflx<0orlx>480 thenlx=-1
164 ifly<0orly>480 thenly=-1
166 iflx=-1then172
168 rem festlegung der lage der achsen
170 fori=lyto1step-30:of=i:next:rem beginn der skaleneinteilung
172 rem start des plottens
174 rem ******************
176 open1,4:print#1,chr$(27);"3";chr$(20);
178 print#1,"f(x)="f$:print#1
180 print#1,"dx="30*dx"      dy="30*dy:print#1
182 print#1,"xa,xe = ("xa","xe")":print#1
184 print#1,"ya,ye = ("ya","ye")":print#1
186 iffs$="j"thenprint#1,"a = ("sw(1);
188 iffs$="j"thenfori=2tosc-1:print#1,","sw(i);:next:print#1,")"
190 rem ausdruck der funktion,definitions,wertebereich,einheiten der x,y achse
192 rem gegebenfalls scharparameter
194 cmd1:rem ausgabe komplett auf drucker,notwendig fuer masch.prog.
196 by=0:ku=-1:co=xa-dx:fori=1toa2step8:bi=256:rem begin der plotsvchleife
198 iffs$="j"thenforaq=1tosc-1:rem falls schar dann alle parameter
200 foru=itoi+7:co=co+dx:bi=bi/2:rem schritte zu 8 fuer ausdruck auf drucker
202 iffs$="j"thena=sw(aq):rem scharparameter
204 poke768,112:poke769,168:yi=fnf(co):rem ausschalten der fehlermeldung
206 rem und bestimmung des funktionswertes
208 ry=int(((yi-ya)*(af-1)/(ye-ya))+.5):rem umrechnen des funktionswertes
210 poke768,139:poke769,227:rem fehlermeldung frei geben
212 ifry<0orry>afthen216:rem funktionspunkt einzeichnen ?
214 pokery+49920,peek(49920+ry)orbi:rem punkt an ausgabepuffer geben
216 ifku>=0thenku=ku+1:rem zaehler fuer einteilung der x-achse
218 ifu=lythenby=bi
220 ifu=ofthenku=0
222 if(ku/30)=int(ku/30)thenvr=1:po=bi:rem skaleneinteilung ?
224 nextu:iffs$="j"thenku=ku-8:co=co-8*dx:bi=256:nextaq:co=co+8*dx:ku=ku+8
226 rem 8punkte fertig machen,dann ev. alle scharparameter durchlaufen lassen
228 iflx=-1thensys49152:nexti:goto240:rem ausgabe auf drucker
230 poke49920+lx,255:rem x-achse setzen
232 ifvr=1thenforq=-1to1:poke49920+lx+q,peek(49920+lx+q)orpo:next:vr=0
234 rem skaleneinteilung
236 ifby<>0thengosub244:rem y-achse ausgeben
238 sys49152:nexti:rem drucken
240 print#1:close1:rem kanal schliessen
242 goto46:rem neue funktion
244 rem
246 forv=49920to49920+af:pokev,(peek(v) or by):nextv
248 iflx=-1thenreturn
250 b1=by/2:ifb1<1thenb1=0
252 b2=by/4:ifb2<1thenb2=0
254 b3=by*2:ifb3>128thenb3=0
256 b4=by*4:ifb4>128thenb4=0
258 ag=b1+b2+b3+b4
260 forzx=0to(af-lx)step30:poke49920+lx+zx,peek(49920+lx+zx)orag:next
262 forzx=0tolxstep30:poke49920+lx-zx,peek(49920+lx-zx)orag:next
264 by=0:return
266 rem y-achse ausgeben und skaleneinteilung vornehmen
10000 deffnf(x)=x
10010 f$="x"
10020 return
Listing 2. Das Hauptprogramm »EPSON-PLOTTER« erzeugt Grafiken wie in Bild 1. Bitte geben Sie es mit dem Checksummer V3 ein.
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →