[Casio fx-6500G]
[Homecomputer C64]
[PC mit DR-DOS]
Buch
Bei meinen "Erkundungen" der Julia- und der Mandelbrotmenge mit dem C64 und dem PC hat mir vor allem dieses Buch geholfen:
Karl-Heinz Becker, Michael Dörfler: Dynamische Systeme und Fraktale, Computergrafische Experimente mit Pascal (2. Auflage, Vieweg 1988)
Dort gab es neben ausführlichen Erklärungen und Beispielprogrammen (in C und Pascal) auch viele Abbildungen interessanter Ausschnitte aus der Mandelbrotmenge nebst Parametern, so dass man nicht selbst "auf gut Glück" herumprobieren musste, was bei einer mehrstündigen Berechnungsdauer pro Bild ein mühsames Unterfangen gewesen wäre. Dem damaligen Stand der Technik entsprechend hatten – bis auf wenige Ausnahmen – sämtliche abgebildeten Grafiken eine Auflösung von 320×200 Pixeln bei 2 Farben (Schwarz und Weiß), so dass die Fraktalbilder hauptsächlich "Höhenlinien" zeigten und keine Farb- bzw. Helligkeitsverläufe wiedergaben. Dies entsprach auch den Fähigkeiten des C64, wobei dieser zwar natürlich Farben darstellen konnte, allerdings hatte ich keinen Farbmonitor, sondern nur einen S/W-Fernseher und einen Einfarb-Nadeldrucker.
Casio fx-6500G
Noch bevor ich einen "richtigen" Computer besaß, programmierte ich ca. 1987 ein »Apfelmännchen« auf dem Grafik-Taschenrechner Casio fx-6500G, dessen Dot-Matrix-LC-Display eine Auflösung von 96×32 Schwarz/Weiß-Pixeln hatte:
(Bilder anklicken zum Vergrößern!)
»Apfelmännchen« auf dem Casio fx-6500G
Leider funktioniert dieses Gerät nicht mehr (durch ausgelaufene Batterien sind diverse feine Leiterbahnen auf der Platine wegkorrodiert), daher kann ich das Programm leider nicht mehr eintippen und vorführen. Die auf dem Display im Bild oben gezeigte »Apfelmännchen«-Grafik ist daher "gefaked" (ich habe sie mit dem JavaScript-Fraktalgrafik-Generator erzeugt und dann mittels Grafikprogramm in das Bild des Taschenrechners hineinkopiert) – aber so in etwa hat es tatsächlich ausgesehen! :-)
Homecomputer C64
Den C64 schaffte ich mir 1989 an, nachdem ich mich zunächst mit dessen "kleinen Bruder", dem VC20 mit 3,5 KB RAM und 23 Zeilen à 22 Zeichen herumgeplagt hatte (den Speicher des VC20 hatte ich später durch eine selbstgeätzte Platine mit zwei "huckepack" aufeinandergelöteten statischen 8K-RAM-Bausteinen zum Einstecken in den User-Port auf stolze 19,5 KB erweitert). Auch wenn die Ära der Homecomputer zu diesem Zeitpunkt eigentlich schon längst vorüber war und jeder einen PC haben wollte (meinen ersten PC schaffte ich mir auch kurz darauf – Ende 1989 – an), war der C64 gegenüber dem VC20 auf jeden Fall schonmal ein riesiger Fortschritt!
Mein C64 hatte schon nicht mehr die typische "Brotkasten"-Form
Als "Monitor" wurde, wie beim C64 üblich, ein Fernseher verwendet – in meinem Fall war das ein portabler Schwarzweiß-Fernseher mit einer Bildschirm-Diaginale um die 35 cm. Zum Speichern der Programme und Daten hatte ich mir noch ein Diskettenlaufwerk gekauft – nicht das doppelt so teure originale "1541" von Commodore, sondern das kompatible und etwas schnellere OC-118N. Gegenüber der "Datasette" des VC20 hatte es nicht nur eine Wahnsinnsgeschwindigkeit, sondern bot auch einen nie dagewesenen Komfort: Endlich kein lästiges Vor- und Zurückspulen der Kassette zu einer bestimmten Zählwerksnummer mehr, um einzelne Programme auf dem Band zu lokalisieren! Und um die Ergebnisse schließlich auch zu Papier zu bringen und so der Nachwelt zu erhalten, hatte ich noch einen 8-Nadeldrucker (Seikosha SP-1000VC), den ich aufgrund des Geräuschpegels allerdings nicht nachts betreiben konnte, wenn ich nicht die anderen Familienmitglieder durch die "Kreischgeräusche" (miiiiiiiep-miiiiiiiiep-miip-miiip-miiiiiiiiiiiiep...) aus dem Schlaf reißen wollte. Computer-Steinzeit halt...
Mein erstes »Apfelmännchen«-Programm war naheliegenderweise in BASIC geschrieben – und grottenlahm: Die Berechnung einer winzigen (aber bildschirmfüllenden) 320×200-Pixel-Grafik dauerte geschlagene 24 Stunden! Außer mit der Mandelbrotmenge experimentierte ich auch noch mit anderen Fraktalen wie z.B. der Julia-Menge und dem Henon-Attraktor. Hier einige der Programme, deren Quellcode ich mir ausgedruckt hatte (immer noch die beste Form der Archivierung...):
Den Bemerkungen in einigen der BASIC-Listings ("BECK IHN 2 S. 283" etc.) deuten darauf hin, dass ich wohl noch ein anderes Buch mit Programmbeispielen hatte, an das ich mich jedoch nicht mehr erinnern kann.
In Assembler habe ich auf dem C64 zuerst mit einem "Maschinensprache-Monitor" programmiert, was alles Andere als komfortabel war, da es hier keine Symbole gab, sondern nur hexadezimale Speicheradressen. Man sprang also beispielsweise nicht zum Label WEITER, sondern zu Adresse C426. Wollte man in bestehenden Programmcode einen Teil einfügen, musste man den nachfolgenden Programmteil um eine bestimmte Anzahl von Bytes im Speicher verschieben und dabei die Ziele aller Sprungbefehle sowie die Adressoperanden aller Lade- und Speicherbefehle anpassen, wofür es extra eine Verschiebe-Funktion gab. Zum Glück stieß ich irgendwann durch Zufall bei Völkner-Elektronik auf das Steckmodul "AS 64" von der Firma Roßmöller, das in einem 8- oder 16-KB-EPROM eine komplette Assembler-Entwicklungsumgebung inklusive Editor und Debugger enthielt – eine wahre Offenbarung! Damit machte es richtig Spaß zu programmieren.
Ich machte mich daran, den Mandelbrot-Algorithmus aus dem BASIC-Programm in Assembler umzusetzen, wobei ich die die arithmetischen Routinen im ROM des C64 benutzte. Die Berechnungszeit für eine »Apfelmännchen«-Grafik schrumpfte dadurch von 24 Stunden auf nur noch 4-5 Stunden, was mich zu dem Programmnamen "Turbo-Apfel" inspirierte. ;-) Vielleicht wäre es noch schneller gegangen, wenn ich eigene Routinen für Fixpunktarithmetik auf der Basis von Integer-Zahlen geschrieben hätte, so wie ich das später auf dem PC gemacht habe, aber auf einem 8-Bit-Prozessor wäre das sicher etwas komplizierter geworden...
Hier zunächst eine Beschreibung der Funktionsweise von "Turbo-Apfel", geschrieben damals auf dem C64:
Hier ein erster Entwurf von "Turbo-Apfel", noch entwickelt mit dem "Maschinesprache-Monitor":
Und hier der vollständige Quellcode der letzten Version von "Turbo-Apfel", schon mit der Assembler-IDE "AS 64" geschrieben:
Wie man sieht, ist der Programmier-Aufwand in Assembler schon erheblich größer als in BASIC...
Allerdings war es mit dem reinen Malen der Grafik auf dem Bildschirm noch längst nicht getan – das Bild sollte ja auch irgendwie abgespeichert und ausgedruckt werden. Standardmäßig war das mit dem C64 nicht möglich, also schrieb ich noch ein weiteres Assembler-Programm namens "HiRes-Hardcopy-Tool" (das "HiRes" bedeutete "High Resolution", also "Hohe Auflösung", und bezog sich auf den Grafikmodus von 320×200 Pixeln...):
Erste Version des "HiRes-Hardcopy-Tools" – man sieht, ist gar nicht so einfach...:
Zweite, verbesserte und erweiterte Version des Hardcopy-Tools:
Dritte und letzte Version des "HiRes-Hardcopy-Tools":
Mit dem Programm konnte man natürlich längst nicht so komfortabel arbeiten wie man das heute gewohnt ist. Ausschnittsbestimmung per Auswahlrahmen beispielsweise war unerreichbarer Luxus. Also mussten Lineal und Taschenrechner zu Hilfe genommen werden. Hier einige Testausdrucke mit entsprechenden Notizen zur Berechnung der zu vergrößernden Bildausschnitte:
Einige der meiner damaligen Ansicht nach besten »Apfelmännchen«-Bilder druckte ich mir mit dem kreischenden Nadeldrucker auf farbiges Papier aus und hängte sie mir im Zimmer auf:
MDBILD/1
(Generator-Link)
MDBILD/3 – Dies war die Vorlage für das »Apfelmännchen«-Poster (s.u.)
(Generator-Link)
MDBILD/4
(Generator-Link)
MDBILD/5
(Generator-Link)
Berechnungszeit mit "Turbo-Apfel" auf dem C64: 5½ Stunden
Berechnungszeit mit JavaScript auf einem Notebook mit Intel Core i7: 45 Millisekunden ;-)
MDBILD/7
(Generator-Link)
Eins der mit dem Assembler-Programm "Turbo-Apfel" entstandenen Bilder (MDBILD/3) habe ich dann als Vorlage für ein Poster genommen. (Aus heutiger Sicht hätte ich allerdings MDBILD/5 besser gefunden.) Das Poster wurde aus 3×3 = 9 einzelnen DIN-A4-Seiten zusammengeklebt. Hierzu habe ich die Parameter der zu druckenden Ausschnitte manuell berechnet. Da die Erstellung einer Seite mit dem C64 vier bis fünf Stunden dauerte und ich tagsüber mit dem Computer arbeiten wollte, hatte der C64 mehrere Nächte lang zu tun. Das anschließende Ausdrucken mit dem 8-Nadel-Drucker (von denen allerdings nur 7 für Grafik-Ausdrucke verwendet werden konnten) war dann immer eine sehr geräuschvolle Angelegenheit... Hier die Skizze zur Berechnung der 9 Teilstücke und ein Testausdruck um zu sehen, ob zwei der Teile auch richtig zusammenpassen:
Das Ergebnis an der Wand meines damaligen Zimmers (Aufnahme vom Dezember 1992 – mit etwas mehr Haaren auf dem Kopf als heute):
Leider habe ich keine der C64-Programme und der damit erzeugten Grafikdateien ins PC-Zeitalter hinüberretten können, da die Diskettenformate von C64 und PC zueinander inkompatibel sind. So schlummern die Programme und Bilder nun auf diversen Disketten, von denen ich nicht weiß, ob diese nach so vielen Jahren / Jahrzehnten überhaupt noch lesbar sind:
Vielleicht gibt es ja in München irgend einen "C64-Club" oder sowas Ähnliches, wo man in der Lage wäre, alte Disketten einzulesen als Image für C64-Emulatoren. Muss ich mich bei Gelegenheit mal erkundigen...
Insgesamt muss man natürlich sagen, dass gemessen am betriebenen Aufwand die erzielbaren Ergebnisse schon sehr bescheiden ausfielen: Auf der "Soll-Seite" standen eine aufwendige Assembler-Programmierung, die umständliche Bedienung und extrem lange Berechnungszeiten. Als Resultat gab es auf der "Haben-Seite" zu verbuchen: Eine niedrige Bildauflösung und als Farben nur Schwarz und Weiß – somit waren keine Farbverläufe darstellbar, sondern nur "Höhenlinien". Trotzdem war es für mich schon damals faszinierend zu sehen, wie aus einfachen Iterationsanweisungen so komplexe Bilder entstehen können, die nicht "programmiert" sind, sondern auf geheimnisvolle Weise von selbst entstehen. Dieses "mathematische Wunder" hatte mich damals schon zu einigen "naturphilosopischen Gedanken" veranlasst, die ich dann auch auf einer DIN-A4-Seite handschriftlich festgehalten habe:
Überlegungen zur Mandelbrotmenge
Mathematik als grundlegendes Element des Kosmos
(handschriftliche Notiz, 1 DIN-A4-Seite, ca. 1989)
PC mit DOS
Mit PCs und dem Betriebssystem DOS kam ich erstmals um 1987/1988 herum in Berührung – also noch bevor ich mir den C64 anschaffte. Einen eigenen PC kaufte ich mir allerdings erst Ende 1989 zu Beginn meines Studiums: Einen "AT" der Marke "Highscreen" von Vobis für genau 2274 DM (keine Ahnung, warum ich mich nach fast 30 Jahren noch so genau an den Kaufpreis erinnere...).
Ich an meinem Highscreen-AT (Foto ca. von 1991)
Mein Highscreen-AT (Foto vom Juni 1996)
Mein erster PC hatte eine 80286er-CPU mit 15 MHz Taktfrequenz, 512 KB Hauptspeicher (später aufgerüstet auf 1 MB), ein 5¼-Zoll-Floppylaufwerk (später noch ergänzt durch ein zusätzliches 3½-Zoll-Diskettenlaufwerk) und eine lahme und laute 20-MB-Festplatte (die ich später durch eine 80-MB-Platte ersetzte). Als Bildschirm diente ein Monochrom-Monitor, der an eine sogenannte "Hercules"-Grafikkarte angeschlossen war. Diesen habe ich später durch einen Farb-Monitor (VGA-Auflösung 640×480, 16 Farben) ersetzt.
Meine ersten Programmier-Versuche auf dem PC habe ich in BASIC unternommen, genauer gesagt mit GW-BASIC von Microsoft, das bei MS-DOS standardmäßig mit dabei war. (Zwar hatte mein Vobis-PC kein MS-DOS, sondern nur den "Klon" DR-DOS, aber irgendwie war ich an eine MS-DOS-3.2-Boot-Diskette gekommen, auf der GWBASIC.EXE enthalten war, das auch unter DR-DOS lief.) Genau wie das C64-BASIC verwendete GW-BASIC Zeilennummern als Sprungziele. Als C64-Umsteiger fühlte man sich daher bei GW-BASIC gleich "heimisch"... ;-) Ich bin dann aber ziemlich schnell – wie bereits beim C64 – zu Assembler übergegangen, wobei ich hier den A86/D86 von Eric Isaacson benuzte. Erst relativ spät habe ich angefangen, in C zu programmieren, wofür ich mir eine verbilligte Studentenversion von "Turbo-C" von Borland kaufte. In den 7 bis 8 Jahren sind so auf dem DOS-PC eine Unmenge an kleineren und auch einige größere DOS-Programme entstanden.
Meine ersten »Apfelmännchen«-Programme auf dem PC schrieb ich in BASIC. Leider existiert der Sourcecode dieser BASIC-Programme nicht mehr – ich habe keine Ahnung, wo diese Programme geblieben sind (wahrscheinlich auf Diskette "gesichert" und später entsorgt, als ich keine Diskettenlaufwerke mehr hatte). Aber da ich früher immer alles auch ausgedruckt habe (ich sage doch: Papier ist das beste Archivsystem...), konnte ich einige dieser Programm-Listings einscannen:
Als ersten Test (wahrscheinlich wusste ich da noch nicht, wie man die Grafikkarte vom Text- in den Grafikmodus umschaltet) schrieb ich ein einfaches Programm (BLOCKAPPL.BAS), das ein »Apfelmännchen« im Textmodus (25 Zeilen à 80 Zeichen) aus Blockgrafik-Zeichen auf dem Bildschirm ausgab. Da das Programm auch Zeichen mit halb gefüllten Blöcken geschickt nutzte, betrug die effektive Auflösung 80×50 "Pixel" (oder besser gesagt "Klötze").
Das nächste BASIC-Programm (FRAKTAL1.BAS) konnte Julia- und Mandelbrotmengen in 2D- und 3D-Darstellung zeichnen und speichern:
Hier einige damit erzeugte Testausdrucke:
Trotz des fehlenden, optional erhältlichen "mathematischen Coprozessors" 80287 war der PC dem C64 geschwindigkeitsmäßig deutlich überlegen. Allerdings dauerte auch hier die Erstellung eines einfachen "»Apfelmännchens«" geraume Zeit (mehrere Minuten).
Einige der mit FRAKTAL1.BAS erzeugten Bilder hatte ich mir auf farbiges A4-Papier ausgedruckt und aufgehängt:
Wie zuvor schon auf dem C64, versuchte ich die Berechnungsdauer von Fraktalgrafiken durch Programmierung in Assembler zu minimieren und so den zeitaufwendigen "Overhead" von Interpreter-Sprachen zu vermeiden. Beim C64 hatte ich zur Berechnung der Iterationen die im ROM enthaltenen Fließkomma-Routinen aus dem Assembler-Programm heraus aufgerufen. So etwas gab es beim PC nicht, und da ja auch der optional erhältliche mathematische Coprozessor 80287 fehlte, behalf ich mir mit einer einfachen 16-Bit-Fixpunkt-Arithmetik, bei der das höherwertige Byte einer 16-Bit-Integerzahl den Wert vor dem Komma und das niederwertige Byte den Wert nach dem Komma enthielt. Vorlage hierfür war vermutlich ein Artikel in einer Zeitschrift – zumindest lassen die Kommentare im Sourcecode ("PC+TECHNIK 2/91, Seite 88-89") darauf schließen.
Von dem Programm existieren unterschiedliche Versionen: Eine für eine Bildschirmauflösung von 320×200 Pixel bei 4 Farben (APFEL320) und eine für 640×200 Pixel und 2 Farben (APFEL640). Es handelt sich lediglich um simple Testprogramme, die nichts weiter machen als ein »Apfelmännchen« mit den eingegebenen Parametern auf den Bildschirm zu malen. Berauschend ist die Bildqualität auch nicht gerade, und selbst in der DOSBox hat die Erstellung der Grafiken noch 25 bzw. 91 Sekunden gedauert. Hier zwei Screenshots davon:
Links APFEL320 und rechts APFEL640
Da die Programme noch in Dateiform existieren, habe ich sie mal in eine ZIP-Datei zum Herunterladen gepackt:
Die ZIP-Datei enthält den A86-Assembler-Sourceode und die ausführbaren COM-Dateien beider Testprogramme.
Ende 1991 schrieb ich einen "Fraktalgenerator" in C, der mit einer für damalige Verhältnisse sehr modernen (block-)grafischen Benutzeroberfläche mit Pulldown-Menüs und Mausbedienung ausgestattet war. Hierzu verwendete ich eine Bibliothek namens "Data Becker C-Toolbox", die es als Buch mit Diskette zu kaufen gab. Als ich diese mehr als 25 Jahre alten Dateien kürzlich in einer Sicherheitskopie meines alten DOS-Festplatteninhaltes wiederentdeckte, war ich selbst überrascht, denn ich erinnerte mich zuerst gar nicht mehr daran, dieses Programm damals geschrieben zu haben... Beim genaueren Ansehen des Sourcecodes kamen die Erinnerung dann aber stückweise (wenn auch nicht vollständig) wieder zurück. :-)
Das Programm enthielt nicht viele Funktionen: Grafikdatei laden und speichern, Parameter eingeben, Testen (= Blockgrafik-Bild erzeugen) und Grafik zeichnen. Die Funktion zum Eingeben der Parameter war zwar schon im Menü hinterlegt, aber noch nicht im Programm implementiert. Zum Zeichnen anderer Ausschnitte aus der Mandelbrotmenge musste daher jedesmal der Sourcecode editiert und das Ganze neu compiliert werden. ;-)
Aus Geschwindigkeitsgründen benutzte das Programm statt der im C-Standard enthaltenen Fließkomma-Datentypen "float" oder "double" eigene, in Assembler geschriebene 32-Bit-Fixpunktarithmetik-Routinen. Außerdem hatte ich noch eine weitere Geschwindigkeitsoptimierung eingebaut: Um nicht jedes einzelne Pixel berechnen zu müssen, wurde der Bildschirm zuerst in lauter Quadrate von 64×64 Pixeln unterteilt und dann für jedes Quadrat die Anzahl der Iterationen für die 4 Eckpixel berechnet. Stimmten diese 4 Werte überein, dann wurde das gesamte Quadrat mit der dazugehörigen Farbe gefüllt. Andernfalls wurde das Quadrat in 4 kleinere 32×32-Pixel-Quadrate unterteilt und derselbe Algorithmus erneut auf jedes dieser 4 kleineren Quadrate angewandt. Hierzu wurde eine rekursive Funktion benutzt. Das ging maximal so lange, bis ein Quadrat nur noch 1×1 Pixel groß war. Bei großflächigen, gleichfarbigen Bereichen wie z.B. dem "Innern des Apfels", wo auch die meiste Rechenzeit "verbraten" wurde, konnte dadurch schon eine erhebliche Beschleunigung erzielt werden. Allerdings konnten dabei auch Bildfehler entstehen, da es durchaus auch Situationen geben konnte, wo zwar die 4 Eckpixel eines Quadrates dieselbe Zahl von Iterationen aufwiesen, der Bereich dazwischen aber nicht. Aber was hat man nicht alles versucht, um die Perfomance der Programme auf dieser schwachbrüstigen Hardware zu verbessern... ;-)
Von dem Programm existierte in meiner Sicherungskopie nur noch der Sourcecode – eine ausführbare Datei war nicht mehr vorhanden. Es ist mir aber gelungen, meine alte DOS-Entwicklungsumgebung mit Turbo-C und TASM in der DOSBox wieder zum Laufen zu bringen und das Programm dort zu compilieren und zu starten, so dass ich einige Screenshots davon machen konnte:
Screenshots des "Fraktalgenerators"
Die in den letzten 5 Screenshots zu sehenden Fraktalbilder liegen im Unterverzeichnis "DAT" als Dateien mit der Endung .DAT vor und können von dem Programm geladen und angezeigt werden. Das Bild-Dateiformat ist sehr einfach aufgebaut: Zuerst folgt ein Byte, das den Videomodus angibt. In diesem Fall ist das 0x13, was dem VGA-Modus (320×200 Pixel mit 256 Farben) entspricht. Danach folgen die eigentlichen Bilddaten, und zwar je Pixel 1 Byte mit dem Farbwert. Im vorliegenden Fall entsprechen die Farbwerte exakt den ermittelten Iterationszahlen. Die VGA-Grafikarte hat diese Werte dann auf eine interne Farbpalette gemappt, die folgendermaßen aufgebaut war:
Mit einem kleinen Zusatzprogramm, das ich geschrieben hatte, konnte man sich diese Farbpalette ansehen und darunter als "Kurve" darstellen, wobei durch Drücken der Tasten R, G und B die Intensitäten (0 bis 255) der Farben Rot, Grün und Blau über das gesamte Farbspektrum hinweg dargestellt wurde:
Die Farbpalette des Videomodus 0x13 (VGA 320×200 Pixel, 256 Farben): Rot, Grün, Blau (v.l.n.r.)
Spaßeshalber habe ich einmal versucht, die Bilddateien mit Paint Shop Pro als Rohdaten einzulesen, was tatsächlich auch funktioniert hat. Natürlich sah man dort nur Graustufen, wodurch sich aber ein gleichmäßigerer Helligkeitsverlauf ergibt. Da die Anzahl der unterschiedlichen Farbwerte aufgrund des gewählten Ausschnittes begrenzt ist, wirkten die Graustufenbilder recht dunkel und kontrastarm. Nach Kontrastverstärkung und Einfärbung mit Paint Shop Pro kamen dann aber doch recht nette Fraktalgrafik-Bildchen zustande:
Die Fraktalbilder als Rohdateien in Paint Shop Pro geöffnet, kontrastverstärkt und eingefärbt
Ich habe alles (Sourcecode, ausführbare Programme, Bilddateien) mal in eine ZIP-Datei gepackt:
OK, soweit also erstmal dieser kleine Ausflug in die "Computer-Steinzeit"... :-)
Homepage > Apfelmännchen in JavaScript > Retro-Apfel