Hallo zusammen :)
Ich habe mir eine Platine anfertigen lassen, mit der ich einen ESP32
über Levelshifter an den Expansion-Port des C64 anschließen und mit
allen benötigten Signalen verbinden kann.
Bisher programmiere ich dieses ESP32-WROOM-32-Board mit 38 Pins über die
Arduino IDE. Ich möchte 8KB von den internen 520KB SRAM nutzen um damit
einen ROM-Chip zu simulieren. Ich habe zwar herausgefunden, wie ich das
Programm in C/C++ schreiben muss um mir ein entsprechend großes
Byte-Array zu erstellen und wie ich das ROM-Image da hinein bekomme.
Wenn ich nun aber über den Interrupt auf den Tackt des C64 warte, dann
die Adresse bittweise einlese über A0-A15 und dann das Byte bitweise auf
die Datenleitungen D0 bis D7 lege, dann ist das zu langsam.
Bei meinen Atmel-Chips konnte ich das damals im Atmel AVR-Studio
deutlich leichter machen. Da habe ich einfach das Byte aus dem
entsprechenden Register geladen oder in das entsprechende Register
geschoben.
Ich stelle mir den Ablauf des Programms wie folgt vor:
- Warte auf Interrupt
- Lese Low Byte der Adresse von Adressbus
- Lese High Byte der Adresse von Adressbus
- Lese das Byte an dieser Adresse aus dem RAM
- Schreibe das Byte auf den Datenbus
Bei einem Atmega wüsste ich in etwa, wie ich das in Assembler machen
kann. Leider ist dieser viel zu langsam für diese Aufgabe. Mit einem
Cyvlone IV FPGA-Chip wäre die Geschwindigkeit kein Problem und da wüsste
ich auch, wie ich das hinbekomme. Diese Lösung ist jedoch deutlich
teurer und bringt einige andere einschränkungen mit sich, die ich dann
anders lösen müsste.
Ich habe auch schon überlegt einen zusätzlichen SRAM-Chip zu verbauen,
mit dem ich in der für den C64 irrelevanten Tackthälfte kommuniziere.
Dann hätte ich bei dem zusätzlichen SRAM pro Tackt des C64 zwei
Lese-Schreib-Zyclen. Einen für den C64 und einen für den ESP32.
Diese Lösung erscheint auf den ersten Blick leichter umsetzbar zu sein.
Dem ist jedoch leider nicht so, weil ich dann für die Zeit, in der ich
mit dem ESP32 auf den SRAM zugreife, die Verbindung zwischen dem SRAM
und dem C64 "kappen" muss um eventuelle ungewollte Auswirkungen zu
vermeiden. Dadurch wird die ganze Schaltung wieder komplexer und teurer.
Wenn jemand eine Lösung für das Problem kennt oder mir sagen kann, wie
ich den Code auch in C/C++ für den ESP32 so effizient schreiben kann,
dass ich den von mir gewünschten Programmablauf realisieren kann, dann
bin ich für jeden Tipp dankbar :)
Gruß
Frank
Ich habe vergessen bei meinen Beschreibungen zu erwähnen, dass der RAM
im C64 eine Reaktionszeit von 100ns hat. Das bedeutet, dass das Signal
innerhalb dieser Zeit auf den Datenleitungen liegen muss. Das
zusätzliche SRAM hätte eine Reaktionszeit von max 12ns und die
Levelshifter von max 33ns. Damit wären wir an dieser Stelle bei max 45ns
in der Summe.
Gruß
Frank
Eine Echtzeit-RAM-Emulation dürfte unmöglich sein.
45 Nanosekunden hieße, das der mit 26MHz angetriebene ESP etwa einen
Takt Zeit hätte sich zu kümmern.
Du brauchst ein Dualport-RAM, das du vom ESP aus beladen kannst, das auf
der anderen Seite dann "normal" funktioniert.
Vielen Dank für deine Antwort Jens :)
Der ESP32 ist ein Dualcore Microcontroller, der mit 240MHz tacktet. Um
die 100ns des C64 RAMs zu emulieren habe ich also 24 Tackte Zeit.
Das mit dem Dualport-RAM ist eine gute Idee. Das schaue ich mir mal an
:)
Danke
Gruß
Frank
Frank Niggermann schrieb:> habe ich also 24 Tackte Zeit.
Un wo ist da das problem?
Um daten aus einem array auszulesen sollte das locker reichen.
Der esp32 ist aber nicht gerade die gute wahl für sowas.
Frank Niggemann schrieb:> dann die Adresse bittweise einlese über A0-A15 und dann das Byte> bitweise auf die Datenleitungen D0 bis D7 lege, dann ist das zu langsam.
GPIO_IN_REG und GPIO_OUT_REG sind Deine Freunde.
Danke für eure Antworten :)
@Jens M.: Ich habe mir gerade mal die Preise für Dualport-RAM angesehen
und das würde den Gesamtpreis vervierfachen.
@Pepe T.: Das Problem ist, dass ich mit dem aktuellen Code deutlich mehr
Tackte benötige, da ich jeden Port einzeln einlese ;) Warum ist ein
ESP32 keine gute Wahl?
@Mario M.: Danke für den Hinweis. Ich werde mal damit rumexperimentieren
und am Oszilloskop die Zeiten messen. :)
Gruß
Frank
Pepe T. schrieb:> Jens M. schrieb:>> 26MHz>> 240 mhz meinst du?
Auch mit 240MHz sind nur knapp 10 Takte um die Adresse zu holen, das
Byte zu lesen und wieder auszugeben, that claps not.
Zumindest nicht wenn die Kiste noch was anderes machen soll, z.B. sich
um typischen ESP-Kram wie WLAN zu kümmern.
Was ginge: den ganzen C64 in den ESP zu laden:
https://github.com/rpsubc8/ESP32TinyC64Frank Niggemann schrieb:> Um> die 100ns des C64 RAMs zu emulieren habe ich also 24 Tackte Zeit.
Oben schraubtest du 45ns.
Aber wenn wir jetzt damit anfangen, dann mal richtig nachgerechnet, denn
ich hab mich oben auch vertan.
Normal ist es so das der Prozessor die Adresse anlegt und binnen 100ns
muss die Antwort da sein, was der normale Chip schafft.
Du musst jetzt zuerst durch die Levelshifts (33ns), dann darf der ESP
überlegen woher er die Daten zieht (a), das legt er an den echten RAM
(b) der dann binnen 12ns liefert. Nun muss der ESP einlesen (c) und die
Ports passend schalten (d), dann wieder zurück durch die Shifts (33ns).
33ns+a+b+12ns+c+d+33ns < 100ns.
a+b+c+d = <12ns.
Bei 240MHz dauert ein Clock 4,16ns, sollte der Chip tatsächlich einen
Befehl pro Clock schaffen, bleiben also ganz knapp 3 Clocks über um ein
Byte auszuliefern.
Nö, wird kein.
Oder überseh ich da was? Man mög mir erklären wo, anstatt wieder 56
Minuspunkte zu vergeben... ;)
Wobei ich mich frage warum die Shifts so lange brauchen wenn das RAM
quasi instant liefern kann, das ist doch weit komplexer?!
Frank Niggemann schrieb:> Ich habe mir gerade mal die Preise für Dualport-RAM angesehen> und das würde den Gesamtpreis vervierfachen.
Tjoa, wer braucht sowas schon noch heutzutage, und dann ist eh alles
knapp und teuer. Mein aktueller Rekord: 3-Achs-Accelerometer,
Mouserpreis knapp 4€, Verfügbar August 23. Jemand anders bietet die für
208€ an, lagernd.
Da sind 40€ für einen Baustein aus den 90ern doch ein Schnapper.
Ich würde nicht einfach davon ausgehen ausgehen, dass die I/O Pins genau
so schnell getaktet sind, wie der CPU Kern.
2x Pin Toggeln per Software dauert offenbar 150ns.
https://www.instructables.com/Faster-ESP32/
Falscher Mikrocontroller. Der ESP32 ist beim PIN toggle eher gemütlich
und "ungenau" bezgl. Timing.
Raspberry RP2040 könnte für deinen Zweck besser geeignet sein. Immerhin
kann der mit Overclocking HDMI per Bitbanging.
https://github.com/Wren6991/picodvi
Müssen die Daten wirklich nach 100ns auf dem Bus liegen?
Der 6510 im C64 hat (in der PAL-Version) einen Systemtakt von 0,98 MHz.
Meines Erachtens sollte da nach Adreß-Setup mehr Zeit bleiben, bis der
Datenbus gelesen wird, lt. Datenblatt kann die Memory Read Access Time
bei 1 MHz Takt max. 575 ns lang sein.
@Stefan F.: Danke für den Hinweis. Das hilft mir weiter.
@someone else: Ich habe mir die Daten des RP2040 mal angesehen. Den
hatte ich bisher nicht in Betracht gezogen. Eventuell hilft das weiter.
Ich werde mir mal einen davon bestellen und schauen, ob es damit geht.
Eventuell kann ich den auch als "Zwischenspeicher" nehmen. Dann hätte
ich das WLAN des ESP32 und die schnelle schaltgeschwindigkeit des
RP2040.
@Jim: Leider ist das nicht so einfach, da die restliche Hardware des C64
ja auch noch eine unbekannte Anzahl X an Nanosekunden benötigt um das
Signal zu verarbeiten. Daher wollte ich möglichst nah an die 100ns des
verbauten RAMs dran kommen.
@Mario M.: Das mit dem Teensy hatte ich auch schon überlegt. Den hatte
ich dann aber auf Grund des Preises erst einmal wieder verworfen.
@Jens M.: Wenn ich keinen separaten SRAM benötige, dann reichen die
Zeiten der Levelshifter aus. Da habe ich noch mal geschaut und es gibt
welche, die bei ca. 15ns liegen. Also hätte ich 2x15ns = 30ns für das
Levelshifting und hätte 70ns Zeit für den ESP32. Die werden aber
anscheinend nicht reichen, da der ja an den Ausgängen so langsam
schaltet.
Vielen Dank an euch alle :)
Gruß
Frank
Frank Niggermann schrieb:> Den hatte> ich dann aber auf Grund des Preises erst einmal wieder verworfen.
Hast du den W806 schon mal angeschaut?
Oder den W801 mit WiFi ?
Beachte dass beim C64 der Speicher auch vom Video-Chip angesprochen
wird, immer abwechselnd. Der RAM muss also doppelt so schnell sein wie
bei einer 1MHz CPU üblich.
Wenn du kein Dual-Port RAM nehmen willst kannst du ein normales RAM
nehmen und das Timing so hin drehen dass der ESP32 das RAM
schreibst/liest wenn weder CPU noch Videochip das machen (also das RAM
ist dann so schnell wie bei einer 4MHz CPU nötig wäre). Wenn du nur hin
und wieder das RAM zugreifen willst, kannst du die CPU auch per "HALT"
Leitung in den Wartezustand schicken, dein RAM aktualisieren, dann die
CPU weiter laufen lassen.
@Pepe T.: Dieses Board kannte ich noch nicht und das scheint es nur als
Import zu geben. Werde ich mir bei Zeiten mal anschauen :) Danke für den
Tipp!
@asd: Das macht die ganze Sache natürlich schwieriger. Zumal der C64 am
Expansion-Port keine Leitung "Halt" hat. Aber dazu habe ich hier etwas
gefunden:
https://codebase64.org/lib/exe/fetch.php?media=base:safely_freezing_the_c64.pdf
Danke
Gruß
Frank
Frank Niggemann schrieb:> Ich habe vergessen bei meinen Beschreibungen zu erwähnen, dass der RAM> im C64 eine Reaktionszeit von 100ns hat.
Laut https://www.c64-wiki.de/wiki/RAM#Modifikationen_von_DRAM-Chips sind
für den RAM Zugriffszeiten bis 350 ns ok.
Frank Niggemann schrieb:> Ich stelle mir den Ablauf des Programms wie folgt vor:> - Warte auf Interrupt
Die ganze Idee von Interrupts ist, dass man nicht warten muss. Wenn du
eh wartest, brauchst du keinen Interrupt.
> - Lese Low Byte der Adresse von Adressbus> - Lese High Byte der Adresse von Adressbus> - Lese das Byte an dieser Adresse aus dem RAM> - Schreibe das Byte auf den DatenbusPepe T. schrieb:> Frank Niggermann schrieb:>> habe ich also 24 Tackte Zeit.
"Takte"
> Un wo ist da das problem?> Um daten aus einem array auszulesen sollte das locker reichen.
Die Frage ist, wie viel Zeit für die Reaktion auf den Interrupt drauf
geht. Das wird vermutlich mit Abstand am meisten Zeit kosten (abgesehen
offenbar vom eigentlichen Pinwackeln).
Rolf M. schrieb:> wie viel Zeit für die Reaktion auf den Interrupt drauf> geht.
Wie du selber schreibst macht ein interrupt hier keinen sinn.
Ein kern soll das pollen, der andere macht wifi.
Die frage ist wie weit sich die dinger gegenseitig behindern.
Beim esp8266, für meine wärmepumpen-auslese-soft musste ich das wifi
abschalten wenn's zeitkritisch wurde. Bei der 71 mal WS2812 anzeige
musste ich sogar interrupts kurzzeitig sperren.
Das esp-wifi scheint bezüglich latenzzeit gutmütig zu sein.
Michael W. schrieb:> Es heißt: Takte - ohne ze-kah!
Nur wenn man sie hören könnte, dürfte man sagen dass sie tickt und
tackt.
(Ja: Deutsch ist unlogisch)
Stefan ⛄ F. schrieb:> (Ja: Deutsch ist unlogisch)
Gut was will man schon von einer Sprache erwarten in der »etwas
umfahren« das Gegenteil von »etwas umfahren« sein kann. ;)
Mir fällt noch ein Cyclone 2 mini dev Board ein. 14 kb Blockram für so
15,-?
Dafür gab es im forum64 sogar schonmal eine Platine.
Wenn es neuer sein soll, mal nach tang nano 9k suchen.