Es beherrscht alles, was das originale CPC-CPLINK konnte, verfügt nun aber über tiefe FIFOs mit 1024 Bytes und die Möglichkeit, Daten über ROM-Images an den Amstrad CPC zurückzugeben.
Im Moment befindet sich das Ganze noch mitten in der Entwicklung, aber im Video unten könnt ihr schon sehen, was möglich ist: Dort wird der Ball auf dem PI Zero gerendert und zur Anzeige an den CPC gesendet.
Gleich geht die „Was macht ihn eigentlich zu einem CPC?“-Diskussion los
Aber es ist wirklich cool.
Für diejenigen, die sich nicht mehr an den CPC-CPLINK erinnern:
Dies ist eine Karte, mit der du einen externen Co-Prozessor, wie einen Raspberry Pi, direkt an jeden Amstrad CPC Computer anschließen kannst.
Die Karte bietet eine einfach zu bedienende parallele Schnittstelle zwischen den Prozessoren mittels First-In-First-Out-Hardware (FIFO) und einem einfachen Software-Protokoll zur Nachrichtenübermittlung (Message Passing). Komponenten zur Pegelanpassung (Voltage Level Shifting) sind integriert, sodass sowohl 3,3V- als auch 5V-Co-Prozessoren direkt angeschlossen werden können. Höchstwahrscheinlich wird der Co-Prozessor ein Raspberry Pi sein, aber die Schnittstelle eignet sich auch für andere Prozessoren und Systeme, einschließlich Arduinos, Teensy und PIC-MCUs.
Das Hauptziel bestand darin, den Datendurchsatz vom PI zum CPC zu erhöhen.
Ja, der CPC-CPLINK2 hat größere FIFOs (jetzt 1024 im Vergleich zu 16), aber das ändert an der Geschwindigkeit der I/O-Anfragen des CPCs eigentlich nichts.
Um das Tempo zu steigern, habe ich einen zusätzlichen GPIO namens „ROM Not FIFO“ (RNF) hinzugefügt. Wenn dieser HIGH ist, wird statt des FIFOs ein Pseudo-ROM im Pico befüllt. Ein zusätzliches Bit im aktuellen Status-Register wird dann gesetzt, um zu signalisieren, dass sich Daten im ROM befinden (es stehen tatsächlich 2 ROMs zur Verfügung). Der CPC kann das ROM dann einfach auswählen (OUT &DFXX, NN) und die Daten kopieren (d. h. LDI).
Er ist also voll abwärtskompatibel zum ursprünglichen CPC-CPLINK, bietet aber diesen zusätzlichen kleinen Trick, um etwas mehr Daten vom PI zum CPC zu übertragen.
Danke, das macht mir wirklich viel Spaß. Ich habe meinen originalen CPC 664 bekommen, als ich 16 war, noch bevor der 6128 auf den Markt kam (also schon eine ganze Weile her), und ich benutze ihn heute immer noch. Projekte dieser Art ermöglichen es mir, den Amstrad CPC immer weiter zu erforschen und zu verstehen. Es macht mir heute noch genauso viel Freude wie damals mit 16.
Kannst du zu diesem Zeitpunkt bereits Programmierdokumentationen bereitstellen? Dann kann ich eine Klasse für dich erstellen, um NTC BASIC damit zu verwenden – ich würde es lieben, die City3D Demo zu sehen, wie sie mit dem Pi als CoProcessor läuft!
Eine Weiterentwicklung der City3D-Demo, programmiert in NTC BASIC – fliege über Auckland, Neuseeland
Ein paar Statistiken:
Fliege im Drahtgittermodell über Auckland, Neuseeland, auf einem Amstrad CPC mit 4 MB
RAM-Erweiterung. Die gesamte Stadt befindet sich im Arbeitsspeicher: 233.935 Gebäude, 43.082 Straßen-,
Schienen-, Küsten- und Wasserlinien, 50.040 Bäume, der Sky Tower, die Harbour Bridge
und die Vulkane – von OpenStreetMap, 409 Quadratkilometer.
VORAUSSETZUNGEN
CPC 6128 oder 464 (Z80, 4 MHz), 4 MB RAM-Erweiterung (200 RAM-Pages oder mehr)
UniDOS mit einem Massenspeicher-Knoten (IDE, SD …): AUCKLAND.DAT ist 3,8 MB groß
(ohne den Blocklesezugriff von UniDOS lädt es Byte für Byte: viel zu langsam)
Dateien: AUCKLAND.BIN (das Programm, 35 KB) und AUCKLAND.DAT (die Daten), auf demselben
Laufwerk. RUN"AUCKLAND
Ich habe die gesamte Analyse und die Tools bereitgestellt, in Kürze auch den C-Code für den Raspberry Pi (den du anpassen können solltest). Du kannst auch das komplette NTC BASIC samt der Demo in Claude einspeisen, und es wird in der Lage sein, die CPC-Seite so umzuprogrammieren, dass die PI-Seite genutzt wird, falls du das brauchst.
CP-CPLINK2-Version (muss eventuell noch etwas angepasst werden, da ich noch keine Karte habe – sollte aber… ohne zusätzlichen RAM laufen!)
Von Claude:
Ich habe die Coprozessor-Version geschrieben: die Engine in C, ein Protokoll für das ROM-Fenster, das die Karte bereitstellt, sowie die CPC-Seite. Die Karte enthält AUCKLAND.DAT, und der CPC benötigt keine RAM-Erweiterung mehr. Es befindet sich in auckland.zip unter coprocessor/ und im NTC-Tree als tools/s3dpi und src/bas/aucklink. Der Z80 zeichnet die Linienlisten der Karte exakt so, wie die C-Referenz es tut (cmp.png: Z80 links, C rechts).
Gemessene Geschwindigkeit: Die Karte übernimmt das 3D, sodass der Frame des CPCs lediglich aus dem Kopieren der Liste aus dem ROM (ca. 45 ms) plus dem Zeichnen besteht:
Ansicht
Linien
Liste
CPC-Frame
FPS
Start
440
1.7K
0.29 s
3.4
Harbour Bridge
300
1.3K
0.22 s
4.5
Devonport
1270
5.6K
0.86 s
1.2
Sky Tower
1400
7.7K
1.13 s
0.9
Das ist das 4- bis 10-fache der Baseline von 0,2–0,4 FPS. Das Zeichnen von Linien mit gfx_line nimmt mittlerweile fast die gesamte Zeit des CPCs in Anspruch und ist somit der nächste Punkt zur Optimierung. Ein geringeres Linien-Budget (B) tauscht Details gegen Geschwindigkeit ein. Die Seite der Karte benötigt auf einem PC 0,03–0,2 ms pro Frame; auf einem RP2040 habe ich es noch nicht gemessen.
Wie die Verbindung funktioniert:
Der CPC sendet pro Frame ein kleines F-Paket: Nick-, Roll- und Gierwinkel (-1, 0 oder 1), Geschwindigkeit, Frame-Skip und Linien-Budget. Es gibt auch Pakete zur Begrüßung („Hello“), zum Springen zu einer Ansicht und zum Abrufen des Namens einer Ansicht.
Das ROM der Karte verfügt über einen Statusblock bei #C100: „S3DP“, wenn es bereit ist, eine Sequenznummer, welche Liste die neueste ist, Linienanzahl, Höhe, Kompass und eine Nachricht. Zwei 7,5K-Zeichenlisten befinden sich bei #C200 und #E000.
Eine Liste besteht aus 3 Bytes pro Punkt (MOVE oder DRAW mit x 0–319 und y 0–199) sowie 1-Byte-PEN- und END-Codes. Jeder Punkt ist bereits auf den Bildschirm zugeschnitten (geclippt).
In jedem Frame wartet der CPC darauf, dass sich die Sequenznummer ändert, kopiert die neueste Liste heraus, sendet das nächste F und zeichnet dann. Die Karte baut den nächsten Frame auf, während der CPC diesen zeichnet, und füllt dabei diejenige Liste, die der CPC gerade nicht liest.
Der C-Code verwendet ausschließlich Ganzzahlen (Integer-only), ein RP2040 ohne FPU reicht also völlig aus:
s3dpi.c / s3dpi.h: die Engine mit denselben Kacheln (Tiles), LOD-Distanzen, Projektionen und dem Linien-Budget wie die Z80-Version.
card.c / card.h: die Kartenseite. Die Firmware der Karte übergibt jedes Paket an card_command() und stellt rom[] als ihr 16K-ROM bereit.
sim.c: führt die gesamte Verbindung in einem einzigen Programm aus und schreibt Bilder sowie eine Listendatei.
host.c: die Engine für sich allein, mit Zeitmessungen.
Was noch unklar ist, bis die CPLINK2-Dokumentation vorliegt:
Ports: die echten I/O-Ports. Link.cls verwendet Platzhalter im M4-Stil: Bytes an #FE00, Trigger bei #FC00.
ROM-Nummer: der Platzhalter ist ROM 6.
Wo die Daten liegen: Wenn sie auf der Karte liegen, benötigt das Board 4 MB oder mehr Flash-Speicher. Der RP2040-Flash ist bei 0x10000000 gemappt, und s3d_open übernimmt einen Zeiger auf die Daten. Alternativ läuft die Engine auf einem PC oder Pi am anderen Ende der Verbindung, und die Karte leitet lediglich Pakete nach oben und 7,5K-Listen nach unten weiter.
Bisher getestet: nur die simulierte Verbindung (sim.c) und der Z80, der eine von sim.c geschriebene Liste zeichnet.
Das sieht super aus. Im Moment konzentriere ich mich darauf, CPC-CPLINK2 zum Laufen zu bringen und es so robust wie möglich zu machen. Ich werde mir das ansehen, sobald ich Zeit habe. Alles, was man über die Verwendung von CPC-CPLINK2 wissen muss, befindet sich auf dieser Folie, einschließlich der I/O-Ports und ROM-Nummern.