erschienen in: GO64! - Das Magazin für Computerfreaks, Ausgabe 12/99

Hello World,

was unterscheidet eigentlich den C64 von einem modernen Computersystem? Zugegeben, eine auf den ersten Blick dämliche Frage, denn jedem ist klar, daß selbst heutige PDAs (auch Palmtops genannt) mehr Rechenleistung in sich vereinen als es unser Brotkasten tut. Doch lassen wir uns von den schieren MHz-Angaben nicht blenden, denn auch hier ist nicht alles Gold, was glänzt: Trotz gleicher Taktrate fallen AMDs K6-Prozessoren unter bestimmten Umständen stets hinter gleichschnell getakteten Pentium II zurück. Des Pudels Kern ist hier der mathematische Coprozessor, auch FPU (von engl. Floating Point Unit) genannt - und genau das soll diesmal auch das Thema von World Watch sein.

FPU - Wozu?

Schauen wir uns mal ein typisches Spiel von heute an: Bei aller technischen Brillanz sind es letztendlich nur Mathematikschlachten. Vektorgeometrie, Strahlverfolgungen, Lichtbrechungen uvm. Hierfür sind eine Vielzahl von Multiplikationen und Divisionen pro Sekunde nötig - so richtig kompliziert wird's dann, wenn Objekte z.B. gedreht werden sollen, denn hier kommen die trigonometrischen Funktionen (Sinus, Cosinus, Tangens) ins Spiel.

Wirklich knackig wird die Sache dann bei einer entsprechenden Auflösung: Hier sollte man wirklich genau rechnen, sonst fallen beispielsweise Rundungsfehler doch massiv ins Auge...

Doch es muß nicht immer ein HighTech-Game von heute sein. Was ist so ziemlich das erste, was ein Demoprogramm in den Speicher schreibt? Richtig: Die Sinustabelle. Was frißt bei Vektorgeometrie so richtig Rechenzeit? Die Multiplikationen - eine 8x8Bit-Multiplikationstabelle wäre dann aber mit 64kB schon wieder zu groß, um sie in den Speicher zu schreiben.

Grund genug, einmal darüber nachzudenken, ob und wie sich ein mathematischer Koprozessor an den C64 anflanschen ließe.

Große Probleme

Herzstück des C64 ist der 6510, ein Abkömmling der 6502-Prozessorfamilie. Commodore liebte diese Prozessoren heiß und innig, und dies nicht nur, weil sie mit MOS Technologies über eine Möglichkeit verfügte, diese Prozessoren in immer neuen Varianten (6502, 6504, 6510, 7501, 8501...) zu fertigen. Was diese Prozessoren damals so attraktiv machte, war der Umstand, daß man mit ihnen sehr leicht ein Multiprozessorsystem aufbauen konnte, denn so ein 6502 ist ein sehr genügsamer Prozessor: Er greift nur während einer Taktflanke auf den Bus zu. Diesen Umstand machte sich Commodore sowohl in seinen IEEE-Floppies zunutze, wo sich ein Prozessor grob gesagt um die Hardwareansteuerung kümmerte, der andere um die Kommunikation - aber auch in den Computern, und so agiert beispielsweise der VIC-II bekanntermaßen während der durch den 6502 nicht genutzten Taktflanke.

Tolle Sache. Allerdings fehlt dem 6502 ein Interface zum Anschluß eines Koprozessors, wie es beispielsweise der 68000 bietet. Wer nun glaubt, der 68000 sei so viel älter, der irrt. Tatsächlich trennen die beiden nur wenige Jahre. Somit kann ein Coprozessor nicht über entsprechend reservierte Opcodes angesprochen werden. Oder etwa doch?

Auch kranke Hirne brüten...

...und manchmal sogar was aus. Stellen wir uns eine Schaltung (Präprozessor) vor, die zwischen CPU und Speicher sitzt und Leseanfragen der CPU an den Speicher entgegennimmt. Liefert der Speicher einen gültigen 6502-Opcode (bevor jetzt alle nach Lachs, Verzeihung, LAX schreien - natürlich gilt dies gleichermaßen für "anerkannte" illegal opcodes) zurück, so wird dieser an die CPU gemeldet, andernfalls wird eine wie auch immer geartete FPU mit dem Befehl beschickt - die CPU bekommt stattdessen NOPs für die Dauer der Ausführung des jeweiligen FPU-Befehls.

Sicherlich eine tolle Idee, allerdings mit etlichen Problemen verbunden, z.B.:

Vorteil dieses Szenarios ist sicherlich die transparente Einbindung eines Coprozessors, d.h. er belegt keinen Speicherbereich und ist direkt mittels eigenen Befehlen ansprechbar. Wo der Haken an der Sache liegt, darauf muß nicht extra hingewiesen werden, oder?

Es muß auch einfacher gehen!

Und das geht's auch. Was enthält so ein Coprozessor im wesentlichen? Tabellen, Tabellen und nochmals Tabellen. Heutzutage ist Speicher billig geworden, in ein einziges EPROM passen bis zu 1MB hinein - warum also noch damit geizen? Somit könnte man über ein kleines Modul beispielsweise folgende Funktionen zur Verfügung stellen:

Einziger Haken an der Sache: Irgendwie müssen wir an die EPROM-Daten ran. Der Einfachheit halber bedient man sich hier des I/O-Bereiches. Zwar brauchen wir hier etwas Logik drumrum, aber wie man mit wenigen Registern z.B. 64kB adressiert, hat uns bereits der VDC des C128 gezeigt: Wir benutzen Segmentregister (hat hier jemand INTEL gesagt?). Über ein Segmentregister wählen wir die gewünschte Tabelle an, welche 256Byte-weise in den Speicher gemappt wird. Nun wird mittels einer einfachen indizierten Adressierung das gewünschte Datenbyte ausgewählt. Um mehrere solcher 64kB-Adreßbereiche ansprechen zu können (die Multiplikationstabelle braucht ja schon 64kB), benötigen wir noch ein zweites Segmentregister. Zu kompliziert? Schauen wir uns nochmals die Grafik an, die beispielhaft die Einbindung des Tabellenspeichers in die C64 Memory Map verdeutlicht:
AdresseRegisterFunktion
$de00Segmentregister 1Auswahl der Funktionensammlung
$de01Segmentregister 2Auswahl der Funktion
$df00-$dfffDatenbereichf(x)
Oder als Code:
	LDA #$00
	STA $de00	; SIN/COS/TAN auswählen
	STA $de01	; SIN auswählen
	LDX #$40
	LDA $df00,X	; sinus von 90 grad "berechnen"
Alternativ für die Multiplikation:
	LDA #$01	; multiplikation auswählen
	STA $de00

	LDA #$faktor1	; multiplikation ausführen
	LDX #$faktor2
	STA $de01
	LDA $df00,X

Und wen interessiert's?

Das ist die grundsätzliche Frage. Ist so etwas für den C64-User überhaupt interessant? Natürlich wäre so ein Modul nur dann nützlich, wenn Software hiervon Gebrauch macht. Deshalb möchte ich an dieser Stelle die Frage stellen, ob Interesse an einem solchen Modul besteht, denn gegenwärtig ist es nur eine Konzeptstudie - und diese ist bei entsprechendem Interesse sicherlich ausbaufähig. Drum der Aufruf: Schreibt mir - per eMail (rainer@buchty.net) - Eure Meinung!