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?

  • Hat etwas gedauert, weil rp2040js dann doch noch nicht ganz so weit war wie gedacht, was Unterstützung von beiden Cores des RP2040 anging... aber jetzt funktioniert's.


    Hab' den PIO-Kram nochmal ziemlich umgestrickt, jetzt passen die Daten für den kompletten Buszyklus in die PIO-FIFOs, und entsprechend lässt sich der ARM-Code beinahe komplett vom Bustiming entkoppeln, ganz ohne IRQs auslösen zu müssen (was in diesem Anwendungsfall viel zu langsam wäre - jeder IRQ macht auf dem M0+ 30/60 Taktzyklen Overhead) oder irgendwie umständlich mit DMA frickeln und synchronisieren zu müssen.


    CIA1 und "CIA2 light" sind jetzt auf den zweiten Core des ersten RP2040 ausgelagert (im Diagramm nicht sichtbar), das Pixelrendering des VIC-II ist auf den zweiten Core des zweiten RP2040 verschoben (auch nicht sichtbar). Als Rest bleibt der Zeitverbrauch der PLA, der CPU und die State Machine des VIC-II (die verbraucht je nach VIC-Zyklus unterschiedlich viel Zeit, links im Bild recht wenig - vermutlich "Refresh" -, rechts im Bild mehr Zeit). Alles in allem ist das (meist) im Moment bei rund 600 ARM-Takten (inkl. Bus-Overhead), noch mit etwas Luft nach unten, aber ein klein wenig muss wohl noch unmittelbar am Code optimiert werden.


    Ich hoffe, dass man die Sprites dann noch in den "ruhigen" Zyklen der VIC-State Machine abhandeln kann, ohne dass das die Kompatibilität zum Original total kaputtmacht. Ist aber wie man sieht alles ziemlich knapp... (ist bisher nur im Emulator getestet, ich hoffe, dass z.B. die weiteren Kapazitäten durch den längeren Bus bei drei RP2040 das Timing nicht deutlich erschweren)


    Die Pixeldaten werden später auf dem gleichen Bus zu PicoDVI übertragen, während die CPU rechnet. Sollte sich mit der zweiten PIO (oder sogar noch mit der ersten PIO als separate State Machine, sofern das Programm noch passt) relativ einfach machen lassen. Also sofern der Bus die dann 9MBytes/Sekunde wuppt... :)

  • Im Simulator funktioniert's schon komplett, in Hardware beinahe: Drei RP2040 zusammengeschaltet, zwei wie im vorigen Posting beschrieben mit CPU/PLA/CIAs bzw. VIC-II bestückt, und der neue "Output"-RP2040 baut aus dem Pixelstream des VIC-II-RP2040 einen Ausgabe-Framebuffer und generiert das Videosignal mit PicoDVI (das wurde vorher auf dem zweiten Core des VIC-II-RP2040 gemacht, aber ließ zu wenig Ressourcen für Originalgeschwindigkeit).

    In Hardware scheint noch was mit dem Signaling von R/W zwischen CPU und VIC-II nicht (wieder) zu funktionieren. Kleinigkeit vermutlich.


    Das Streaming der Pixel zwischen VIC-II und Output funktioniert. Das läuft in der Idle-Time des "alten" Busses (während CPU/VIC "rechnen"), und das mit einem RP2040 mehr am Bus und mit ganz schön knappem Timing (rund 50ns pro Schritt). Ich bin etwas platt, dass das aus dem Simulator rauskopiert direkt ging.


    Die Pixeldaten werden im VIC-II-RP2040 von einer zweiten PIO State Machine abgehandelt: so verstopfen sie nicht den 4-Word-FIFO der ersten State Machine (die sich um die ganzen "normalen" C64-Bus-Sachen kümmert). Passt alles von der Programmlänge her gerade noch in eine PIO. Auf zwei PIOs hätte man das wohl auch gar nicht aufteilen können, weil die GPIOs nur einem Ziel zugeordnet werden können, also nicht beide PIOs auf einen GPIO schreiben können.


    Wenn das mit dem Bus so entspannt ist, bekommt man später auch noch die Audiodaten drüber (mit noch einem RP2040 für den SID...). Netterweise hat auch gerade jemand in PicoDVI Sound implementiert. :)

    Das oberste (schwarze) Board ist übrigens ein WeAct-RP2040 mit 16MB Flash (statt 2MB), USB C statt Micro, zusätzlichen Buttons für Reset und Custom Function und mehr verfügbaren GPIOs, dafür fehlen die Castellated Edges.

  • Läuft jetzt mit korrektem Bild und mit den beiden RP2040s für CPU und VIC-II auf 400MHz. Gold Quest 6 ist geschwindigkeitsmäßig jetzt sehr gut spielbar, wenn auch noch nicht auf Originalgeschwindigkeit.


    Im Moment bin ich an m6502.h dran, einmal ist dort das für den 32-Bit-RP2040 etwas unhandliche uint64 als Repräsentation für den Bus drin, zum anderen muss eh was besseres her, weil es so nicht möglich ist, den 6510-Tick Teilparallel mit PLA und Holen der Daten vom Bus laufen zu lassen: Die Busdaten müssen m6502_tick() direkt beim Aufruf mitgegeben werden, obwohl in der Tick-Funktion selbst erst gegen Ende auf die Busdaten zugegriffen wird. Da PLA+m6502_tick() schon mehr als 200 ARM-Zyklen (von 400 verfügbaren) brauchen, würde das also im Zusammenspiel mit den anderen Komponenten knapp (nicht, wenn nur auf RAM/ROM zugegriffen wird, da das nicht über den Bus geht, aber alles andere - I/O, ColorRAM - halt schon). Außerdem wäre schön, auch die PLA wenigstens prinzipiell auf einen anderen ARM-Kern als den 6510 auslagern zu können.


    Ist schon ulkig - die paar Zeilen Code, um die es hier geht, laufen auf einem PC vermutlich in maximal wenigen Dutzend Nanosekunden durch, und ohne es gemessen zu haben würde ich schätzen, dass die Kommunikation zwischen den Kernen bei einem x86 zu teuer ist, um solche Optimierungen lohnenswert zu machen...

  • Noch ohne die in #43 erwähnte Optimierung jetzt (etwas wackelig) bei meistens 450 ARM-Takten, wird also.


    Bei der PLA-Geschichte hab ich gestern gerätselt, wieso sie eigentlich BA als Eingang braucht. Das wird wohl nur für das IO- und das CASRAM-Signal benutzt. CASRAM brauche ich hier nicht, bleibt IO, da haben wir z.B. für die _HIRAM=1, _CHAREN=1-Config das hier:

    Code
    1. _I_O = _HIRAM & _CHAREN & A15 & A14 & !A13 & A12 & BA & !_AEC & R__W & _GAME (p1)
    2. | _HIRAM & _CHAREN & A15 & A14 & !A13 & A12 & !_AEC & !R__W & _GAME (p2)

    ...ausformuliert:

    Code
    1. IO enabled:
    2. BA==1 R__W==R => IO=1 no VIC DMA planned, read (p1)
    3. BA==1 R__W==W => IO=1 no VIC DMA planned, write (p2)
    4. BA==0 R__W==W => IO=1 VIC DMA planned, write (p2)
    5. IO disabled:
    6. BA==0 R__W==R => IO=0 VIC DMA planned, read

    Also schaltet die PLA in der Config I/O nur dann aus, wenn

    • AEC aktiv, also Kontrolle des Busses bei CPU (aber s.u.) oder ExpPort-Modul
    • VIC-II hat DMA per BA=0 angekündigt (aber DMA läuft noch nicht, da AEC noch aktiv)
    • Bus Read (aber: BA=0, d.h. CPU ist bereits inaktiv, da sie bei BA=0 nur noch Writes "fertigmacht")

    Also kann in dem Fall nur ein Expansionsportmodul lesen (und, wenn ich das richtig sehe, eigentlich auch nur "Reste" aus dem CPU-Zyklus davor, da es noch keine Kontrolle über die Adressleitungen hat).

    Wieso dieser Sonderfall? Das sollte nur in den drei Takten passieren, bevor der VIC dann wirklich DMA macht? Und bevor BA auf 0 geht, sieht ein DMA-Expansionsportmodul TROTZDEM I/O - das dann aber verschwindet, sobald der VIC BA auf 0 zieht? <- das war Unsinn, bei BA=1 kann ein Modul ja kein DMA machen.

    Oder stehe ich da auf dem Schlauch? Wer kennt sich denn da aus? Frenetic  kinzi  skoe ?


    Ah (ha, Duck Debugging!), kann es sein, dass der VIC-II während BA=0/AEC=1 keine Reads aus seinen Registern unterstützt? Hm. Aber Writes schon? Wär auch komisch.


    Edit: Die Hoffnung bei der Überlegung ist, dass man sich evtl. BA als Input der PLA (wenigstens sofern man wie hier Phi Low nicht emuliert) sparen könnte. AEC (den anderen wesentlichen PLA-Input) habe ich im Emulator "kostenlos" und zeitnah (ohne erst den VIC fragen zu müssen) nach jedem CPU-Tick vorliegen, wäre also performancetechnisch geschickt.

  • Ah (ha, Duck Debugging!), kann es sein, dass der VIC-II während BA=0/AEC=1 keine Reads aus seinen Registern unterstützt? Hm. Aber Writes schon? Wär auch komisch.

    Glaube ich nicht.

    Aber der VIC muss auf das Char-ROM zugreifen können, egal ob es die CPU ausgeblendet hat oder nicht. Und das macht er bei BA=0.


    [EDIT]


    Vielleicht liegt auch ein Verständnisproblem vor: "IO" hat nichts mit Expansionport zu tun.

    (Vielleicht ist das Verständnisproblem auch bei mir ... :-D .)


    [/EDIT]

    "Wenn du überredet, ermahnt, unter Druck gesetzt, belogen, durch Anreize gelockt, gezwungen, gemobbt, bloßgestellt, beschuldigt, bedroht, bestraft und kriminalisiert werden musst. Wenn all dies als notwendig erachtet wird, um deine Zustimmung zu erlangen, dann kannst du absolut sicher sein, dass das, was angepriesen wird, nicht zu deinem Besten ist." - Quelle unbekannt.


    "Steve Jobs hat User hervorgebracht, Jack Tramiel Experten." - Quelle unbekannt.

    "Mein Herr, ich teile Ihre Meinung nicht, aber ich würde mein Leben dafür einsetzen, dass Sie sie äußern dürfen." - Voltaire.

    "Diskutiere nie mit einem Idioten - er zieht dich auf sein Niveau hinunter und schlägt dich dort mit seiner Erfahrung!" - Volksweisheit.


  • Aber der VIC muss auf das Char-ROM zugreifen können, egal ob es die CPU ausgeblendet hat oder nicht. Und das macht er bei BA=0.

    Aber doch nicht bei BA=0 und AEC=1?


    Edit: Wegen IO, ja, es ist klar, dass es um die Enable-Leitungen für CIAs/SID/VIC im Bereich D000-DFFF geht - ich hatte in #44 nur überlegt, welche Komponente in welchem Szenario überhaupt auf den Bus zugreifen könnte und gemutmaßt, dass es in dem Fall des "fehlenden" Terms um Module gehen könnte.

  • "Wenn du überredet, ermahnt, unter Druck gesetzt, belogen, durch Anreize gelockt, gezwungen, gemobbt, bloßgestellt, beschuldigt, bedroht, bestraft und kriminalisiert werden musst. Wenn all dies als notwendig erachtet wird, um deine Zustimmung zu erlangen, dann kannst du absolut sicher sein, dass das, was angepriesen wird, nicht zu deinem Besten ist." - Quelle unbekannt.


    "Steve Jobs hat User hervorgebracht, Jack Tramiel Experten." - Quelle unbekannt.

    "Mein Herr, ich teile Ihre Meinung nicht, aber ich würde mein Leben dafür einsetzen, dass Sie sie äußern dürfen." - Voltaire.

    "Diskutiere nie mit einem Idioten - er zieht dich auf sein Niveau hinunter und schlägt dich dort mit seiner Erfahrung!" - Volksweisheit.


  • Am PLA liegt _AEC an, das kommt vom 7406, der die Muxer treibt.


    Diese beiden Terme steuern IO für CPU-Zugriffe.

    IO ist das Signal für VIC, SID, CIA1, CIA2, IO1 und IO2, das durch den 139 weiter aufgedröselt wird auf die einzelnen IO-Chips.


    Und natürlich ist das nur gültig, wenn AEC=1 bzw. _AEC=0, sprich !_AEC=1.


    Und wenn BA=0 und damit ein DMA angekündigt ist, darf IO beim Lesen IO nicht mehr ziehen. Das Lesen wird dann bei BA=1 (erneut) nachgeholt.

    Beim Schreiben natürlich schon noch, der Schreibzyklus muss ja noch beendet werden können; daher muss auch der IO-Baustein, der angesprochen werden soll, noch ein /CS erhalten.


    So interpretiere ich das.


    Mit dem Char-ROM-Zugriff, wie zuerst vermutet, hat das gar nichts zu tun, das ist Blödsinn von mir.

    Das wird ja über das /CS des Char-ROMs (PLA-Ausgang "/CHARROM") erledigt.

    "Wenn du überredet, ermahnt, unter Druck gesetzt, belogen, durch Anreize gelockt, gezwungen, gemobbt, bloßgestellt, beschuldigt, bedroht, bestraft und kriminalisiert werden musst. Wenn all dies als notwendig erachtet wird, um deine Zustimmung zu erlangen, dann kannst du absolut sicher sein, dass das, was angepriesen wird, nicht zu deinem Besten ist." - Quelle unbekannt.


    "Steve Jobs hat User hervorgebracht, Jack Tramiel Experten." - Quelle unbekannt.

    "Mein Herr, ich teile Ihre Meinung nicht, aber ich würde mein Leben dafür einsetzen, dass Sie sie äußern dürfen." - Voltaire.

    "Diskutiere nie mit einem Idioten - er zieht dich auf sein Niveau hinunter und schlägt dich dort mit seiner Erfahrung!" - Volksweisheit.


  • Und wenn BA=0 und damit ein DMA angekündigt ist, darf IO beim Lesen IO nicht mehr ziehen.

    Warum? Denn aktiviertes IO würde in der Situation auch nicht stören, weil sowieso weder die CPU (da BA=0/AEC=1, Read) noch der VIC (da AEC=1) vom Bus liest.

    Wenn das so ist, könnte man BA aus den Termen für die IO-Leitung gleich ganz weglassen und hätte deutlich weniger Terme oder gar (sofern BA in den CASRAM-Termen auch nur ein Artefakt ist) BA gleich ganz aus der PLA weg.

    Und an letzteres mag ich nicht so ganz glauben. ;)

  • Weil dann z. B. fälschlicherweise ein IRQ ACK in einem CIA ausgelöst werden könnte?

    (Nur mal als ein Beispiel.)


    Die CPU verarbeitet diesen Befehl nicht mehr bei R/W=1.

    Nur bei R/W=0 beendet sie den Schreibzyklus normal.


    Der Lesezyklus wird erneut gestartet (und dieses Mal mit aktiviertem /CS) nachdem BA wieder auf 1 geht.

    "Wenn du überredet, ermahnt, unter Druck gesetzt, belogen, durch Anreize gelockt, gezwungen, gemobbt, bloßgestellt, beschuldigt, bedroht, bestraft und kriminalisiert werden musst. Wenn all dies als notwendig erachtet wird, um deine Zustimmung zu erlangen, dann kannst du absolut sicher sein, dass das, was angepriesen wird, nicht zu deinem Besten ist." - Quelle unbekannt.


    "Steve Jobs hat User hervorgebracht, Jack Tramiel Experten." - Quelle unbekannt.

    "Mein Herr, ich teile Ihre Meinung nicht, aber ich würde mein Leben dafür einsetzen, dass Sie sie äußern dürfen." - Voltaire.

    "Diskutiere nie mit einem Idioten - er zieht dich auf sein Niveau hinunter und schlägt dich dort mit seiner Erfahrung!" - Volksweisheit.


  • Das "Interface" der CPU-Emulation m6502.h war bisher ein einzelnes uint64, das die Pins des Prozessors abbildete. Charmantes Design, aber ineffizient, weil so Daten und IO-Port etc. für den Zugriff immer maskiert und geshiftet werden mussten, außerdem ist der RP2040 nur 32bittig, muss also mit dem uint64 immer etwas jonglieren. Also eigene Variablen für Adresse, Daten und IO-Port genommen, bleiben nur 7 Bits/Pins übrig (AEC, RDY, IRQ, NMI, RW, SYNC, Reset).


    Dadurch und durch Folgeeffekte ist das alles wieder ein kleines Stück schneller geworden. Alleine dass die CPU-Port-Bits für die PLA jetzt "freiliegen" hat die PLA 30% schneller gemacht (38 statt 55 ARM-Takte); der CPU-Tick ist meist etwa 18% schneller und liegt jetzt im Bereich von 100-190 ARM-Takten (letzteres ist ein Dezimal-ADC, langsamer wird's glaube ich nicht).


    Als nächstes dann die Optimierung aus #43 zum Lesen von VIC-II-Registern bzw. ColorRAM (das wird dann den Tick wegen Fallunterscheidung im Average Case wieder minimal langsamer werden lassen, aber dafür den Worst Case viel besser machen) und dann mal schauen, ob ich die in den letzten Postings besprochene Abhängigkeit von BA noch entspannt bekomme. Die CPU muss nach einem Tick immer auf das BA-Signal durch den VIC-II warten. Ohne diese Abhängigkeit wäre etwas mehr Luft. Eine Idee wäre, den VIC-II leicht zu modifizieren und ihn BA einen Takt früher ziehen zu lassen (was sich dann mit einem 1-Takt-Delay in der CPU ausgleicht). Der Preis wäre, dass die VIC-II-Emulation bei Rasterzyklus 55/56 nicht ganz exakt ist (dort wäre das Timing gegenüber der CPU "sichtbar" um einen Takt verschoben). Wäre glaube ich verschmerzbar...?

  • Wobei ich gerade bei dem Stable Raster-Kram den "Künstliche Badline"-Trick sehe. Dass man per D011 mitten in einer Zeile das Badline-Flag setzen und damit BA=0 setzen kann, hatte ich in m6569.h übersehen. STA schreibt natürlich erst im letzten Teiltakt, entsprechend muss sofort im nächsten Takt von der CPU das vom VIC-II erst auf das STA hin gelieferte BA=0 berücksichtigt werden. :/ Mal weiter überlegen...

  • War 'ne längere Pause, aber es geht langsam weiter. Erstmal "Spaß" mit einem Heap Overflow nach Update des gcc gehabt, das hat mich ein paar Stunden gekostet...


    Neuigkeiten:

    • Mein Fork von rp2040js ist jetzt NOCH genauer: Die PIOs haben keinen Jitter mehr (vorher haben sie nach jedem ARM-Befehl "aufgeholt" und so bis zu 8 Takte als einen Schritt ausgeführt). Vorher gab es häufiger Effekte wie "Video hat in Emulation Pixelschnee, aber in echt nicht" und umgekehrt, das ist jetzt weitgehend weg. Man müsste noch die Verzögerung der Signale durch Laufzeiten/Kapazitäten modellieren, aber rp2040js ist für den Moment schon langsam genug. ;)
    • Ich habe einen kleinen "Hat" gebastelt, mit dem sich eine Original-C64-Tastatur, zwei Joysticks und (später) auch eine Floppy anschließen lässt. Möchte ja wissen, wer bei Commodore auf diese seltsame Reihenfolge der Port-Leitungen beim Tastaturanschluss kam...
    • Das läuft mit einem über einen PS/2-Adapter angeschlossenen Tastatur auch prima (siehe Anhang. Unterster Pico: HDMI-Output, bekommt Pixeldaten vom VIC-Pico darüber, der wiederum mit dem CPU/CIA/RAM-Pico darüber spricht, der über den "Hat" mit dem PS/2-Adapter und dem Joystick verbunden ist).
      • Der PS/2-Adapter hatte hier noch einen sehr seltsamen Bug und initialisierte mit meiner alten Tastatur nur wenn über den Pico mit Strom versorgt nicht richtig (da die Tastatur dann anscheinend deutlich nach dem Adapter initialisierte und der Adapter dann aus dem Tritt kam).
      • Man könnte natürlich auch einen weiteren Pico als USB-Tastatur-Adapter nehmen und den auch gleich am Bus die CIA1 emulieren lassen, aber das lasse ich für später.
      • Das hier ging übrigens nur mit dem "WeAct"-Pico-Clon, denn es werden 9 GPIOs für Bus und Takt/Strobe gebraucht PLUS 16 GPIOs für CIA1/Tastatur/Joysticks PLUS 3 GPIOs für IEC - der normale RPi Pico bietet aber nur 26 GPIOs. (auch beim WeAct fehlt erstmal die Leitung für die RESTORE-Taste, aber der hat ja noch einen User-Button :) ).

    Next: Weiteres Verbessern des Profilers im rp2040js-Emulator, sodass ich von den VCD-Traces wegkomme, die doch eher anstrengend zu lesen sind und auch nicht gut erkennen lassen, an welcher Stelle im Code welcher Core gerade ist.

  • Next: Weiteres Verbessern des Profilers im rp2040js-Emulator

    Nimmt Form an:

    Der Code ist mit Marken instrumentiert ("cpu tick end" und "cia tick start" und so weiter), sodass man nicht alles im Disassembly nachschauen muss, was auch bei angeschalteter Optimierung des Compilers schwierig wäre.

    Die Marken sind für die ARM-Cores "transparent" und tauchen im Disassembly einfach als was in der Art "bl skip, data MAGIC, data STRING, skip:" auf und kosten den Core entsprechend nur zwei Taktzyklen pro Marke.

    Meine Variante von rp2040js schaut bei jedem bl nach, ob danach das MAGIC kommt, und schreibt den STRING mit, falls dem so ist.


    Hier läuft der FIFO des PIOs des VICs leer, soll heißen, in Bus-Phase 4 (da werden in der Welt dieses Projekts die eigentlichen Daten geschrieben/gelesen) gehen der PIO State Machine des VIC die Instruktionen aus: Instruktion Nr. 3 der VIC-PIO - "VIC_PIO@3" - ist ein PULL, das aus dem FIFO einen uint32 holen sollte. Der Emulator bzw. der Run-Code für das Projekt prüft während der Emulation die Stall-Bits der PIO und beendet die Emulation, falls ein Stall auftritt.


    Das lief alles vorher als Code direkt auf dem ARM, was aber mächtig Runtime-Performance kostete, in Sachen Nebenläufigkeit nicht gut ging und die Bastelei mit der (emulierten) Seriellen auch unhandlich war.


    Das Timing hier ist etwas tragisch, da man im Trace sieht, dass der ARM-Core bereits im Code zur Behandlung eines Idle Fetches ist - "reg nop" - aber damit zu spät ist. Genaugenommen hat wohl bereits der VIC-Tick vorher etwas zu lange gedauert, muss ich nochmal schauen.

  • Die Trace-Funktionalität aus dem Posting vorher ist tatsächlich sehrsehr praktisch. Da ist aber noch einiges zu werkeln, bis das alles im Timing-Fenster klappt. Speziell Zyklus 16 und 17 beim VIC-II sind im Moment knapp. Tatsächlich hat der RP2040 dann die Hände voll mit Speicherzugriffen, genau wie damals der VIC-II. :) Obendrauf das Bus-Handling (will die CPU in VIC-Register schreiben oder lesen?) dauert noch etwas zu lange, wobei es nur um ca. 100 ARM-Taktzyklen geht. Hätte doch der RP2040 einfach drei Cores oder 600 statt 400MHz... ;)


    Aber an anderer Stelle gibt es Erfolg: IEC/Floppy-Zugriff geht jetzt grundsätzlich! Im Anhang ein Bild vom LOAD"$",8 von einem angeschlossenen SD2IEC, das ich vor über einem Jahrzehnt für den C64DTV gebaut hatte und das nur 3,3V spricht. Hat auf Anhieb (nach Abschalten der Badlines, sonst ist's eben noch zu langsam) funktioniert!

  • Mal gemessen (brrr), wie schnell die GPIOs eigentlich sind. Zieht man per PIO einen GPIO auf High, erkennt ein damit verbundener GPIO das nach ca. 20ns bzw. 7 Taktzyklen bei 400MHz, ziemlich gut reproduzierbar. Vielleicht baue ich das doch nochmal in rp2040js ein, kann ja eigentlich nicht so schwer sein(tm). Interessanterweise machen die Slew Rate- und Drive Strength-Einstellungen des RP2040 wenig Unterschied, bei mehr als 4mA Drive Strength gibt's eigentlich nur mehr Überschwinger.


    Das Ding wird übrigens im Juli hier zu sehen sein: Tagung zum C64 in Bonn :)

  • ...und noch ein paar RP2040-spezifische Erkenntnisse: Bei den Zeiten gestern handelt es sich wohl um erster Linie um interne Latenzen, nicht Rise/Fall-Zeiten, worauf sowohl dieses Posting als auch die Tatsache hindeutet, dass die PIO selbst generierte 200MHz relativ sauber lesen kann.


    Außerdem habe ich noch etwas mit den Pullups experimentiert. Die internen Pullups sind recht schwach und schaffen nur ca. 1V/µS. Ein Pullup-Input, der von 0V "losgelassen" wird, braucht ca. 2µS, bis er als High gelesen wird. Das ist natürlich als Shared Pin für IRQ/NMI so dann ungeeignet, weil im 1µS-Buszyklus hier mehrfach zwischen diversen Flags, Adressen und Daten gemultiplex wird.


    Aber mit z.B. 1K zu 3,3V dran sieht das schon viel besser aus, dann hat man etwa 3V/100nS und 60nS, bis der Pin als High gelesen wird (bei 4mA Drive Strength), was rund 20 Taktzyklen bei 400MHz entspricht. Der Widerstand stört beim normalen Push-Pull-Betrieb auch nicht. Damit könnte man schon eher arbeiten.


    Das ist interessant, weil ich bisher davon ausgegangen bin, dass Pullup-Signalisierung bei den hohen Busgeschwindigkeiten, die man hier mit nur einem 8-Bit-Bus hat, nicht funktioniert. Dann bräuchte man dedizierte GPIOs für IRQ/NMI, wenn man z.B. die CIAs in einem separaten RP2040 machen wollte. Schlecht, weil GPIOs insgesamt knapp sind und dann das "symmetrische" Hardware-Design dahin wäre. Aber das ist dann wohl zum Glück gar nicht nötig. (wobei man evtl. Tricks machen könnte wie zu Beginn der IRQ/NMI-Signalisierung die jeweiligen Leitungen hart kurz auf High ziehen und dann loslassen und den Pullup die Leitung halten lassen. Kostet halt ein paar PIO-Instruktionen, und beim VIC ist da schon kein Platz mehr)

  • Ein paar Optimierungen beim Rendering des VIC-II gemacht und endlich sind die 406 ARM-Taktzyklen, die für die 0,98MHz des C64 zur Verfügung stehen, erreicht. :emojiSmiley-92:

    Noch ein paar 1k-Pullups an die IEC-Leitungen angelötet und tatsächlich funktioniert JiffyDOS mit einem SD2IEC auf Anhieb und ohne weitere Klimmzüge.

    Das ist Meilenstein Nummer 4 aus der Liste aus Posting 2 hier und soweit ich weiß was Microcontroller-basierte C64-Emulation angeht ein World First. :)

    Ich gehe davon aus, dass auch Transwarp etc. geht, muss ich irgendwann ausprobieren.

    Einige weitere Spiele wie z.B. Karateka oder Wavy Navy funktionieren auch.


    Fehlt noch Sound (dürfte relativ einfach sein: SIDKick pico nehmen, die Busroutinen anpassen und die Daten in den HDMI-Strom einbauen).


    Vor allem fehlen aber die VIC-II-Sprites. Da bin ich etwas ratlos. Die rund 400 Pixel pro Zeile normale Grafik verbrauchen im Moment sowas wie 80% eines CPU-Kerns, und der andere Kern geht größtenteils für die State Machine des VIC-II drauf. Dann noch maximal 384 Pixel (acht doppelt große Sprites in einer Zeile) dazu plus Prioritätslogik (die im Moment komplett fehlt) sehe ich da nicht so ohne weiteres. Ich hatte etwas in diversen Emulatoren geschaut, aber die machen alle keine Magie, sondern gehen tatsächlich für jeden Pixel einer Zeile alle Sprites plus den Hintergrund durch. Das schafft ein RP2040 auf keinen Fall in der zur Verfügung stehenden Zeit. Man könnte noch etwas tricksen (z.B. kann man zum Ausdekodieren der Sprites teilweise eine PIO zweckentfremden), aber spätestens die Kollisionserkennung und Umsetzung von Transparenz muss die CPU machen, soweit ich das sehe. Bisschen ärgerlich, weil man ansonsten einfach die PIO die Pixeldaten per DMA in den Speicher schreiben lassen könnte, ganz ohne CPU-Last, mit etwa 40 Pixeln pro Mikrosekunde, also mehr als ausreichend schnell. Oder man flanscht noch einen RP2040 ran, macht da eine vereinfachte VIC State Machine nur für die Sprites drauf und schickt den Sprite-Pixelstrom zum HDMI-RP2040, der den und den normalen Grafik-Strom verwurstelt, dafür hat der noch Resourcen. Aber das wird dann auf dem Bus und mit der Sprite-Kollisionssignalisierung etc. pp. ganz schön wild. Dann vielleicht lieber auf den RP2040-Nachfolger warten. ;)


    Na mal weiter überlegen und vielleicht ein paar Testprogramme schreiben.