Hello, Guest the thread was viewed9.9k times and contains 67 replies

last post from 1570 at the

C64-Rebuild auf 3,3V-Basis mit X uCs möglich?

  • Marketing-Sprech: Läuft jetzt 7x so schnell wie am 23. Januar und die PIO rennt mit ganzen 3MHz!!!!1!


    Dass ein Phi-Halbzyklus mit dem aktuellen PIO-Code 173 PIO-Taktzyklen braucht (und der Quotient PIO-Programmlänge / PIO-Takt ~= 60 noch "ein Stück" :rolleyes: vom nötigen Wert 0.5 entfernt ist), kann man ja erstmal unter den Tisch fallen lassen. :)


    Auf jeden Fall debuggt sich das jetzt schon halbwegs brauchbar: Falls in den ersten paar tausend 6510-Zyklen auf dem Bus was anderes passiert als in einem Trace vorgegeben, hängt sich das Ding auf und gibt über USB den Grund und ein Log der letzten Bus-Aktivitäten raus.


    Was das Problem in #18 war, ist etwas unklar. Vermutlich eine Mischung aus etwas sehr straffem Timing beim Übermitteln der Adresse auf dem Bus plus ein leichter Wackelkontakt. Bit 7 ist wirklich in allen Kontexten ständig störrisch.


    Die PIO lässt sich problemlos höher takten und das PIO-Programm kürzen, dann hakelt's aber wieder auf dem Bus bzw. der C-Code kommt nicht hinterher, auch im Emulator. Mal die Tage weiterschauen.


    Sehr schick ist beim RP2040 übrigens, dass man sich über Kurzschlüsse/Kollisionen auf dem Bus keine Sorgen machen muss, da geht nichts kaputt. Man kann den maximalen Ausgangsstrom sogar pro GPIO einstellen.

  • Die PIO ist jetzt bei 8.4MHz, bei noch rund 163 PIO-Zyklen pro Phi-Halbe ergibt das also rund 20µS. Dreimal so schnell wie gestern und nicht mehr weit bis 0.5µS! ;)

    Habe noch einen Fehler in der Emulation gefunden, der für etwas Jitter zwischen den beiden MCUs gesorgt hat.


    Angehängt ein Screenshot des (virtuellen) Logic Analyzers. Zeitangaben sind 1000er ARM-Ticks, nicht µS. "clock" ist eigentlich eher "strobe" (vom CPU/PLA/RAM-RP2040). "ack" ist Interna des VIC-RP2020, analog zu "clock" werden dort bei steigender Flanke Daten auf den Bus gelegt und bei fallender Flanke vom Bus gelesen.

    Bei A ist das High-Byte der Adresse auf dem Bus, bei B das Low-Byte und bei C die Daten. Konkret ist das ein $3FFF Idle Fetch des VIC-II (der ein $FF aus dem RAM holt). Man sieht auch ein paar kleinere Glitches auf dem Bus, dass ich mich bei den VIC-PIO-Zyklen beim Punkt C wohl etwas verzählt habe und dass die beiden ARM-Cores ziemlich viel Däumchen drehen (main_busy/vic_busy unten). In anderen Phasen ist das allerdings leider nicht ganz so - wenn z.B. der Code für die beiden CIAs läuft, wird das jetzt schon am Ende des Buszyklus knapp. Muss mal schauen, was speziell bei den CIAs da so langsam ist.

  • Modelliert der Emulator denn auch die Waitstates der APB-Bridge

    Jetzt macht rp2040js das schon, wenigstens in Ansätzen. Und die drei Varianten von LDR, bei denen Waitstates vergessen wurden, sind jetzt auch gefixt. :)


    Ist schon übel: Alle Befehle, die auf SRAM zugreifen, brauchen insgesamt (mindestens) zwei ARM-Zyklen. Also schnell ist der M0+ nicht, auch nicht bei 400MHz...

  • Ich finde das Projekt sehr interessant und frage mich folgendes:


    Wenn man deinen ersten RP2040 für CPU, PLA, RAM, CIAs (Core 1) sowie SID (Core 2) nimmt sollte doch ein Plugin Board für den CPU Sockel machbar sein, klar müssten ein paar Levelshifter drauf.

    Die SID und CIA Nachbildung macht im CPU Sockel eher keinen Sinn die PLA "intern" genutzt schon, um Verbindungen nach außen zu sparen.

    ROM könnte man ebenfalls nachbilden und komfortabel schaltbar machen.

    Dieses Modul sollte sogar recht universell sein und mit leichten Anpassungen als 7502/8502 oder eine andere 6502 Variante arbeiten können.


    Den weiten RP2040 könnte man dann an den VIC II Steckplatz adaptieren als eine kostengünstige Alternative zum Kawari nutzen.

    was denkst du?


    Kennst du dieses?

    https://www.raspberrypi.com/ne…spberry-pi-pico-emulator/

    https://github.com/cknave/c64-pico-ram-interface

    Seine Testumgebung könnte interessant sein.

    Da er den Bus nicht multiplexed der Rest eher weniger.


    Dies hier hilft möglicherweise beim SID Teil:

    https://codeberg.org/CBMretro/PicoSID


    Ich nehme an dieses Projekt hat dich auf die Idee gebracht?
    https://github.com/jfoucher/picovic


    Im MCUME Projekt schient die c64 Emulation mit einem PI recht gut zu funktionieren.

    https://github.com/Jean-MarcHa…UME/blob/master/README.md

    Daher bin ich optimistisch das ein cycleexakter VIC-II möglich ist.

  • Bei der CPU könnte das eventuell schon gehen, ich weiß gerade nicht, wie das Timing des originalen 6510 genau ist. Bei dem Projekt hier kann (und muss) man das Gesamttiming ziemlich schieben, während beim Original mehrere Teilsegmente eines Buszyklus relativ flexibel sind, aber Maximallatenzen etc. einhalten müssen.

    In der Praxis heißt das, dass ich hier, wenn z.B. die C-Emulation deines 6510-Ticks einfach unumstößlich länger braucht als durch die aktuelle Arbeitsversion des Busprotokolls in "Daten vom Bus lesen, IRQ-Flags vom Bus lesen, TICK, Adresse auf Bus legen" erlaubt, einfach das Busprotokoll ändern kann (mehr Zeit für TICK, weniger Zeit irgendwo anders). Die Freiheit hat man im Original natürlich nicht.

    Etwas ähnliches gibt es für den 6510 schon fertig: https://github.com/MicroCoreLabs/Projects/tree/master/MCL64 - erreicht aber so wie's da ist wohl nur mäßige Emulationsgüte, und die nur mit einem deutlich schnelleren Microcontroller. Hab ich mir nicht im Detail angesehen.


    Beim VIC-II wird's dann aber ganz wild mit seiner super-seltsamen Anbindung über letztendlich insgesamt drei Busse, die teilweise gekoppelt dann aber doch wieder nicht sind und allesamt sehr timingkritisch sind (CAS/RAS läuft effektiv mit 4MHz oder sowas?). https://c64os.com/post/flitiming1 hat dazu Details (ersten Abschnitt ignorieren). Schon alleine von den GPIOs her bekommt ein RP2040 das nicht gestemmt - der VIC-II hat mehr als 32 Signal-Pins. Von dem nötigen Videosignal-Output noch ganz zu schweigen...

    Das kann ich mir in diesem Projekt alles sparen - hier hat der VIC exakt den gleichen Bus wie die CPU (ist auch "nativ" 16bittig am Adressbus) und muss sich nicht um Refresh des System-RAMs oder ähnliches kümmern. Falls sich herausstellen sollte, dass der RP2040 wirklich deutlich zu schwach ist, kann man hier auch einfach Phi Low ganz kippen und dem VIC gespiegeltes System-RAM geben, schon haben alle Komponenten die doppelte Zeit zum Arbeiten (aber die komplexeren Expansionsportmodule werden dann auf keinen Fall mehr laufen). Im Kontext "Chip-Drop-In" geht das auch nicht.


    Eventuell kann man den Code, der hier rauskommt, nachher als Basis für Ersatzbauteil-Projekte weiterverwenden. Für einen Drop-In-Ersatz des VIC-II wird der RP2040 sicher nicht reichen, und insgesamt wär's bis dahin ein weiter(er) Weg, der mich persönlich eher nicht interessiert. Wäre einfach ein ganz anderes Projekt für ggf. einen anderen Thread. :)


    Edit:

    https://www.raspberrypi.com/ne…spberry-pi-pico-emulator/ ist letztendlich ein per RP2040 umgesetztes Expansionsport-Modul. Das PIO-DMA-Zeugs ist dafür nicht wirklich nötig (aber natürlich cool, das alles ohne die ARM-Cores machen zu können). Der RP2040 wäre schnell genug, das einfach alles in C/über die ARM-Cores zu machen. Ist jedenfalls ein ganz anderes Projekt.

    Die Testumgebung, die er dafür gebastelt hat, hmja. Ist halt nicht verfügbar, und ich vermute, er wird da schlicht was in Richtung "Abspielen vorher aufgenommener Signalsequenzen" implementiert haben und dann mit einem Logic Analyzer dran gemessen haben, das wäre ja sinnvoll in dem Kontext.


    Ich mach das halt alles in rp2040js, damit's nicht fünf Jahre dauert. :)


    Edit2:

    MCUME schließlich scheint eher für einfache Spiele gedacht und emuliert CPU und VIC-II nur in groben Zügen: https://github.com/silvervest/…pico/pico64/cpu.cpp#L2037 - zyklenexakt ist da weder die grundsätzliche Implementierung noch das Echtwelt-Timing (auch der VIC-II wird dort zeilenbasiert emuliert, was deutlich weniger Ressourcen frisst, aber eben auch nicht korrekt ist). Ist ein nettes Projekt, aber mit völlig anderen Zielsetzungen als hier.

  • Erstmal wollte ich sagen, hab oben noch ein paar Sachen ergänzt.

    Mit dem VIC-II hast du recht ich hab vergessen das das Color RAM ja auch an der CPU hängt ist halt schon einige Jahre her.

    Alleine schon wegen des Preises wäre ein RP2040 deutlich interessanter als ein Teensy 4.1 für den CPU Ersatz, wenn das aber nicht möglich ist, ist das so.

  • Ist schon übel: Alle Befehle, die auf SRAM zugreifen, brauchen insgesamt (mindestens) zwei ARM-Zyklen.

    Einen zum Lesen des Befehls, einen zum Speicherzugriff? Der M0 hat ja nur einen AHB-Port für alles, getrennte Ports für Befehle und Daten gibts IIRC erst ab Cortex M3.

  • Unseen Ja, irgendsowas. Speicherzugriffe sind beim RP2040 nur im SIO-Adressraum "kostenlos".


    Ich bin vom gcc-Optimizer nicht überzeugt. Eben in einer Funktion in m6526.h zum Spaß eine temporäre Variable für c->ta.pip eingeführt, das in der Funktion mehrmals referenziert wird (und das der Compiler dann doch bitte automatisch bei -O3 entsprechend erkennen und optimieren sollte). Hatte keinen Unterschied erwartet, spart an der Stelle aber tatsächlich rund 10% Zyklen (und diese eine popelige Funktion braucht über 100 Zyklen...). Das wird noch ein Haufen Kleinzeug, so wie's aussieht.

  • Die Geschichte ist jetzt bei um die 2000 ARM-Zyklen = 6.7µs pro Phi/2 (und die PIO bei rund 30MHz). Dafür mussten allerdings schon die Timer der CIAs dran glauben, weil deren cia_tick erstaunlich lange braucht, aber die kann man ggf. später auslagern (mit drei RP2040: ein Core CPU und Co, ein Core CIAs, zwei Cores für den VIC-II, zwei Cores für Framebuffer/PicoDVI. SID gibt's dann erstmal nicht :) ). Hat auch den Vorteil, dass man die Emulations-RP2040 dann mit 400MHz fahren kann; im Moment sind die wegen des PicoDVI-Pixeltakts auf 295MHz festgenagelt. Für den Moment habe ich auch die Gesamtlänge eines Zyklus flexibel gemacht: Das nächste Phi fängt an, wenn CPU/CIA/VIC fertig mit ihrem Emulations-Tick sind. Das ist fürs Testen so erstmal okay, aber ist natürlich nicht mehr wirklich exaktes Timing.


    Und was gelernt, mit den aktuellen Settings des RP2040 hier brauchen die Pins von "aktiv Low gerade losgelassen" zu "erkannt High via Pullup" etwa 0,2µS. Als Teilphase eines gemultiplexten um-die-10MHz-Busses ist das natürlich zu langsam. Eventuell bekommt man das in den Griff, indem man die Leitungen zu Beginn der jeweiligen Busphase kurz aktiv auf High zieht, das lasse ich aber für später. :)


    Als nächstes müsste ich wohl das PIO-Programm ziemlich umschreiben. Insbesondere sind große Teile noch "synchron": In der ersten Busphase z.B. wird die Adresse auf den Bus geschrieben und danach gelesen (kann ja sein, dass der VIC lesen will); der C-Teil läuft erst weiter, wenn die Lesephase auch fertig ist, obwohl dieses Warten z.B. in Phi1/AEC1 nicht nötig ist (weil dann immer die CPU am Hebel ist). Die Frage ist allerdings, ob solche Optimierungen viel bringen, weil ja letztendlich der Worst Path das Timing bestimmt. Evtl. bringt es auch was, die PIO via DMA wenigstens teilweise am C-Code "vorbei" ihre Daten holen zu lassen (das sollte z.B. bei den meisten PLA-Signalen gehen), aber das gäbe dann sehr RP2040-spezifischen Code plus "schöne" potenzielle Race Conditions...

  • Um die 1200 ARM-Zyklen, PIO bei 150 MHz, mit echtem Joystick dran und auch wieder Unterstützung für Multicolor. Gold Quest 6 läuft (sehr langsam). Als nächstes ist vermutlich etwas Verschieben von Zeugs zwischen den Cores angesagt.


    Unseen Weißt Du zufällig, ob die originalen IEC-Routinen mit Jitter auf dem Bus klarkommen? Ich hab hier nämlich noch ein ganz altes 3,3V-only-SD2IEC noch von/für einen C64DTV entdeckt, das ich evtl. einfach direkt testweise anbauen könnte... :)

  • Weißt Du zufällig, ob die originalen IEC-Routinen mit Jitter auf dem Bus klarkommen?

    Der Takt kommt (beim Laden) von der Floppy, die jittert am echten Rechner nicht mehr oder weniger als an deiner Konstruktion.

  • Da absehbar ist, dass der RP2040 auf keinen Fall genug Rechenleistung für die Emulation von beiden Taktphasen hat, habe ich (wieder) gespiegeltes C64-RAM und Bus Snooping in den VIC eingebaut und die Emulation von Phi Low abgeschaltet. Das hat die Geschwindigkeit wie erwartet etwa verdoppelt, und das Gesamtwerk schafft jetzt (unter Nutzung von zwei Cores für die Emulation und nach wie vor ohne Sprites) etwa 30% Originalgeschwindigkeit. Anbei auch noch der Beweis, dass Choplifter keine Sprites benutzt.


    Kurz überschlagen schätze ich, dass CPU (m6502.h) und PLA nicht weiter optimiert etwa 1000 Coremarks für Echtzeit benötigen, der VIC-II (m6569.h) irgendwas zwischen 1200 und 4000 Coremarks und jede CIA-Instanz (m6526.h) etwa 1100 Coremarks.


    Ein einzelner RP2040-Kern bringt bei 400MHz rund 800 Coremarks. Bleibt also spannend.

    Als Vergleich, ein ESP32 bringt auf einem Kern wohl rund 600 Coremarks.

    Der NXP iMXRT1062 auf dem Teensy 4 bringt bei 800MHz rund 3200 Coremarks.

    Ein typischer Desktop-Prozessor liefert sechsstellige Coremarks.

  • Siehe #26 - man könnte eventuell einiges aus dem Code für Chip-Replacements weiterbenutzen, aber nach meiner aktuellen Einschätzung geht da mit dem RP2040 sicher nichts (beim VIC-II) und vermutlich nichts (beim 6510), einfach weil dem RP2040 die Rechenleistung fehlt und im originalen C64 die Anforderungen an das Timing nochmal höher sind.


    Gleichzeitig bin ich mir ziemlich sicher, dass z.B. ein CPU-Ersatz mit dem Teensy möglich ist, wobei MCL64 ja auch genau das schon macht. Ist halt bei Preisen um die 30€ für den Teensy im Moment nicht so attraktiv, und was das Projekt hier angeht ist die CPU das kleinste Problem. :)

  • Hmja... wie oben geschrieben ist der m6526.h-Code so wie er im Moment ist zu langsam, da ist viel Bitshifterei und Maskierung drin, was der Cortex M0+ nicht so mag, und der Code implementiert noch nichtmal die TODs im Moment. Andererseits hätte man bei einem Chip Replacement zwei M0+-Cores für eine CIA zur Verfügung. Schwer zu sagen. Wie das mit den bidirektionalen Pins und Level Shifting gemacht werden kann, weiß ich auch nicht. Mit 5€ wird da eher nichts zu holen sein.


    Zurück zum Thread-Thema. Sprites! Kann man vielleicht auch per RP2040 umsetzen, indem man das Rendering (nur) der Sprites direkt im s-Fetch macht. Mit dem gespiegelten RAM macht der emulierte VIC-II zu der Zeit nämlich relativ wenig (das Rendering des Borders/Grafik passiert später im anderen Core). Oder gingen so irgendwelche gängigen Sprite-Effekte kaputt?

  • Der Wegfall von Phi Low erlaubte einige Optimierungen, z.B. hat so die CPU immer die Kontrolle über den Adressbus, was vorher nicht so war. Entsprechend kann man beim RP2040 einfach die Adresse in die FIFOs der PIO schreiben und schonmal weiterrechnen. Außerdem muss die PLA nicht mehr potenziell auf die Adresse von außen warten und braucht als Input "von außen" nur BA vom VIC.


    Außerdem habe ich mir m6526.h nochmal genauer angeschaut und einige Optimierungen gemacht, dank einer LUT braucht ein CIA-Tick jetzt nur noch rund 230 ARM-Takte.

  • PLA+RAM/ROM+CPU zusammen sind jetzt bei rund 400 ARM-Takten. :emojiSmiley-92:

    Das sollte also passen. (vermutlich wird's noch ein paar Ausreißer geben, muss mal genauer z.B. bei den Dezimalmodus-Opcodes nachschauen, aber das wird man schon irgendwie hinbekommen)


    CIA1 wandert ja noch in den anderen RP2040-Core und sollte da auch (zeitlich) reinpassen.


    Der VIC-II liegt insgesamt noch bei (meist) rund 950 Takten, muss also für zwei Cores noch etwas optimiert werden. Plus die Sprites halt...


    Der (virtuelle) Logic Analyzer für den Bus sieht jetzt ganz ulkig aus, man kann recht gut den jeweiligen VIC-Status erkennen (im Anhang).

    C und H: Badlines (anderes Zugriffsmuster auf den Datenleitungen), D, E, F, G...: Border (VIC deutlich weniger Busy).


    Die echte Hardware liegt erstmal wieder etwas brach, ich muss den dritten Pico noch umlöten, und im Moment tut rp2040js auch ganz gut - die virtuelle Bildschirmausgabe ist z.Zt. einfach als Dump des Framebuffers aus dem RAM des VIC-RP2040 in ein GIF auf der Host-Platte implementiert, ähnlich wie bei der Emulator-Variante, die direkt auf dem PC läuft (tolle IFDEF-Hölle übrigens, tut aber!). Später fliegt der Framebuffer im VIC-RP2040 dann raus, stattdessen werden die Pixeldaten über den Bus in den dritten RP2040 laufen, der sich dann exklusiv um HDMI/DVI out kümmern wird (später könnte der dann auch noch über den gleichen Weg Audiodaten vom SID annehmen und über HDMI ausgeben).