Hallo Besucher, der Thread wurde 6,4k mal aufgerufen und enthält 40 Antworten

letzter Beitrag von cbmhardware am

AVR direkt am CPU-Bus ?

  • Es wurde eigentlich schon mit dem SwinSID realisiert, aber hat sich jemand vielleicht schon weiteren Experimenten in dieser Richtung versucht ?


    Ich habe einen ATMega88P mit 20Mhz-Quarz auf einem Steckboard. Ich hatte in verschiedenen Postings gelesen, dass auch 24 und 32Mhz durchaus machbar sind.


    Reizt mich doch, da mal am Expansionsport des C64 zu versuchen, was damit machbar ist. :) Der AVR wird dann mit GAVRASM ( http://www.avr-asm-tutorial.net/index.html ) programmiert. Den hatte ich 2007 schon mal verwendet und lese mich im Moment wieder ein.


    Aber vielleicht gibt es ja schon andere Experimente ?

  • Per AVR (oder bel. uC) SID/VIC/RAM oder den Bus komplett zu
    treiben sollte nicht so schwer sein. Der uC agiert in diesem Fall
    als Master. IO-Konflikte müssen nur per SW aufgelöst werden.


    Dein Vorhaben ist aber, den AVR als Slave an den Bus zu hängen,
    und damit wird deinem uC das Timing aufgedrückt, d.h. Deine
    SW muss hölilsch aufpassen um IO-Konflikte zu vermeiden
    (falls das überhaupt komplett gelingt). Abhilfe wären ggf.
    Bustreiber wie ls245 etc.


    Mit einem FPGA wär's leichter, habe ich auch schon gemacht.
    Auch SID/VIC anzusteuern ist relativ leicht.

  • Ich werde wohl zuerst versuchen per I/O1 oder I/O2 einfach mal ein Byte zu schreiben und das dann per LEDs visualisieren. Da wäre dann ein Bustreiber zum Isolieren des Lesezugriffs keine schlechte Idee.
    Als nächsten Schritt könnte man dann mal testen, wie gut es klappt, wenn man R/W mit auswertet.


    Schreibe erst mal den EQU-File für den Mega88 und mache mich im Laufe der Woche dann mal an erste Tests.

  • Das Problem, wenn du vom AVR lesen willst hat auch der SwinSID. Deshalb kann man von ihm nichts lesen.


    Du hast beim C64 von dem Moment an dem dein I/O-Signal meldet, daß die CPU was will bis zu dem Zeitpunkt an dem du den Bus wieder freigeben muss bei einem 20 MHz-Quarz noch nicht einmal 10 Takte (*).


    In der Zeit musst du auf das Signal reagieren, rausfinden was gewünscht wird, diese Daten auf den Bus legen und den Bus zur korrekten Zeit wieder freigeben. Letzteres kann man mit dem 74LS245 entschärfen, den Rest leider nicht.


    (*) 500ns wären 10 Takte, davon geht noch die Durchlaufzeit durch die PLA und die beiden 74LS139-Hälften ab.

  • (*) 500ns wären 10 Takte, davon geht noch die Durchlaufzeit durch die PLA und die beiden 74LS139-Hälften ab

    Tja, maximal sind wohl 32Mhz machbar. Darüber hinaus soll ein AVR so langsam in nicht reproduzierbares Fehlverhalten übergehen.


    Das wird eng. Man könnte R/W auch erst mal als INT-Quelle auswerten und per SBI oder CBI dann den Lesezugriff per Bustreiber blockieren. Der nächste Schritt wäre dann Zyklenknausern und sehen ob es noch passen kann, wenn man etwas auf den Bus legen möchte.

  • Nimm einfach IO1 immer zum schreiben und IO2 immer zum lesen, dann kannst du R/W ignorieren.
    Und wenn du zu dem noch jedes lesen "anfordern" musst durch ein entsprechendes schreiben vorher (also dann bereits den puffer fuellen und beim lesen nur auf den bus legen) dann sollte das drin sein... aber nicht sehr komfortabel.


    EDIT: mit einem CPLD bist du da aber wirklich besser dran, ich hab' schon einige male mit dem XC9572 (PLCC) gearbeitet. Und z.Z. bastele ich mit einem PSoC 5 Kit rum (das ist ein 80MHz ARM und CPLD in einem, voll 5V kompatibel).

  • Status des Registers ein/ausgabe Registers auf "Low",
    Und Schreibzugriffe durch das Richtungsregister.
    Also
    Ausgang + Status Low= BUS Low
    Eingang + Status Low = Bus High durch Pullups.


    Ein 80Mhz 3,3V Controller hat funktioniert mit ein paar Dioden und Wiederständen als "Level Shifter", und durch das vermeiden der Harten auf 5V schalten gibs auch keine Zerstörerischen Busskollisionen.


    Als C64 Diagnosemodul irgendwie mal geplant, aber nie aus dem ersten Wurf rausgekommen...

  • Und was bei der Taktrate auch noch mit berücksichtigt werden
    muss: Eine Erweiterungskarte ist für die Adressdekodierung selbst
    verantwortlich, d.h. Du musst mit deinem AVR je Addresse einen
    Vergleich auf deinem Addressraum machen und bei Lesezugriffen
    dann entsprechend die Daten-IO-Pins auf Ausgang schalten.
    (20-24Mhz => deine CPU hat dann keine Zeit mehr für sonstige
    "Aktivitäten")


    Wurde ja schon angesprochen: 5V-tolerante Pins. Es muss aber
    nur 5V akzeptiert und nicht ausgegeben werden, 3.3V-Level reicht
    schon. Hab's jedenfalls mal mit einem XC9572XL (3.3V-Variante)
    eine einfache LED-Schaltung gebastellt.

  • Eine Erweiterungskarte ist für die Adressdekodierung selbst
    verantwortlich

    Nicht zwingend, denn ROML, ROMH, IO1 und IO2 sind bereits dekodiert: je eine einzelne Leitung die man ganz schön und einfach an einen Interrupt legen kann.


    Hab's jedenfalls mal mit einem XC9572XL (3.3V-Variante)
    eine einfache LED-Schaltung gebastellt.

    Die XC9500XL's sind ja auch explizit als 5V kompatibel gebaut worden. Bei ebay bekommt man aber auch noch die ohne XL dann ist alles 5V.

  • Nicht zwingend, denn ROML, ROMH, IO1 und IO2 sind bereits dekodiert: je eine einzelne Leitung die man ganz schön und einfach an einen Interrupt legen kann.

    Genau so wurde es beim Swinsid auch gemacht: http://www.swinkels.tvtom.pl/swinsid/files/swinsid.asm.


    Wenn der C64 noch 10 Takte beim Wechsel von R/W hat, ist der hochgetaktete AVR in diesem Moment mit seinen 1-2 Zyklen Befehlen vielleicht in der Lage, dann passend zu reagieren. Der darf dann natürlich nicht anderweitig allzu beschäftigt sein.

  • Das wäre wohl etwas zu umständlich. /IOx und R/W könnte man mit einem 139er Dekoder auswerten und dann zwei INT-Eingänge damit belegen.


    Ich habe mir schon einen Mega1284P hingelegt. Bei den kleinen AVR liegen die INT-Ports dummerweise im einzigen 8 Bit-Port.
    Wenn das klappen sollte, muss man sowieso nach dem Schreibzugriff den AVR erst mal kurz arbeiten lassen, der puffert dann die anfallenden Daten, um die bei(m) nächsten Lesezugriff(en) dann bereitzustellen.
    Traumhaft wäre es natürlich, wenn der kurz den Speicher per AEC _DMA und BA selbst übernimmt, um dann dort direkt seine Daten abzulegen. Wäre auch mal einen Ansatz wert.

  • Der Ansatz den AVR den Bus übernehmen zu lassen ist nett, aber auch problematisch. Schliesslich kannst du den Bus nicht komplett übernehmen sondern nur immer nur den CPU-Teil. Der VIC besteht auf seinem Recht (und seinen Badlines). Womit wir wieder bei den 500ns max (= 10 Zyklen bei 20 MHz) wären. Beim Schreiben ins RAM wären dann noch die diversen Zeiten für Setup der Daten und Adressen zu beachten. Deine Adressen müssen stabil anliegen wenn der VIC /RAS auf LOW zieht.


    Es ist gar nicht so einfach in Software das zu tun was eine in den 70/80ern designte Logik problemlos kann.


    Die Pausenzeiten nach dem Zugriff auf den AVR sind weniger das Problem, schliesslich muss der 6502 ja selbst die Befehle laden und ausführen. Ein


    STA $xxxx
    LDA $xxxx


    müsste 70 oder 80 Zyklen (für den AVR) Pause zwischen den Zugriffen auf den AVR ergeben. In 70 Zyklen kann man mit einem AVR schon einiges machen. Das Problem ist nicht das Schreiben zum AVR, das zeigt der SwinSID. Das Problem ist das lesen vom AVR.

  • Die Pausenzeiten nach dem Zugriff auf den AVR sind weniger das Problem, schliesslich muss der 6502 ja selbst die Befehle laden und ausführen. Ein


    STA $xxxx
    LDA $xxxx


    müsste 70 oder 80 Zyklen (für den AVR) Pause zwischen den Zugriffen auf den AVR ergeben.

    Das wird deutlich weniger, wenn man mit RMW-Befehlen (zB INC/DEC) zugreift. Da sind zwar auch Dummy-Zugriffe dabei, aber die kann der AVR nicht so einfach von echten unterscheiden.


    Zitat

    Das Problem ist das lesen vom AVR.

    Wenn man damit komplett eigene "Hardware" entwerfen will und nicht zu etwas bestehendem kompatibel sein muss, könnte man das mit Zugriffen nach VDC-Art etwas entschärfen: Eine Adresse um eine Registernummer zu setzen und eine zweite, um von diesem Register zu lesen oder zu schreiben - der AVR müsste dann für Lesezugriffe nur den Wert des gerade ausgewählten Registers bereithalten und nicht gross rumdecodieren, was denn gemeint sein könnte.


    Wenn man da noch ein wenig Hardware ergänzt (externe Latches um das zuletzt geschriebene und das nächste zu lesende Datenbyte zu speichern) könnte man das Timing vermutlich auch nochmal deutlich entschärfen. Einige PICs haben sowas unter dem Namen "Parallel Slave Port" schon eingebaut und mit den schonmal erwähnten PSOC4/5-Chips von Cypress könnte man sowas auch leicht mit den eingebauten konfigurierbaren Logikblöcken konstruieren.

  • Eine Adresse um eine Registernummer zu setzen und eine zweite, um von diesem Register zu lesen oder zu schreiben - der AVR müsste dann für Lesezugriffe nur den Wert des gerade ausgewählten Registers bereithalten und nicht gross rumdecodieren, was denn gemeint sein könnte.


    Etwas ähnliches habe ich vor. IOx und R/W wird mit einem 139er Dekoder verknüpft und auf INT0 (C64 schreibt) bzw. INT1 (C64 liest) geteilt.
    Beim Schreiben muss der INT dann das Richtungsregister setzen, Datenbyte und evtl. Adressleitungen (für Register) lesen.
    Beim Lesen dann Datenrichtungsregister auf Ausgang und Datenbyte raus. Dazwischen muss der natürlich noch etwas (damit) machen.

  • Das ist der Versuchsaufbau fürs Wochenende: AVR ATMega1284P (erst mal 20Mhz), ein 74ls139 und ein 74LS245er Bustreiber.



    IO1 und R/W steuern den Bustreiber. Zugleich wird der 139er mit I/O aktiviert und R/W für INT0, INT1 in Read und Write aufgeteilt. Sobald I/O1 nicht mehr selektiert ist, trennt der Bustreiber die Datenleitungen (High-Z). So lange der AVR selektiert ist, fangen die beiden INT-Eingänge die Zugriffe auf.


    Ist so natürlich nicht alles in Beton gegossen, prinzipiell müsste es imo so aber schon klappen.


    Da sind dann soweit alle Erkenntnisse aus diesem Thema eingeflossen. Zum Programmieren komme ich dann am Wochenende. Musste noch einen Breadboard ISP-Adapter löten, den Assembler für Linux i386 kompilieren und alles zusammensuchen.


    Wer möchte sich zu einer Prognose hinreißen lassen, ob am Wochenenden von einem AVR gelesen wird ? :)

  • avra unterstützt die "neueren, großen AVR" noch nicht. Bei diesem gavrasm sind 644 und 1284p schon drin, haben aber scheinbar auch kleine Fehler.
    Ich habe jetzt einen 644p drauf und takte mit einem 32Mhz-Oszillator. Funktioniert mit einem 20Mhz-Quarz aber genauso gut. Schreiben ist gar kein Problem, aber R/W macht welche. Einerseits hat der Dekoder damit merkwürdiges Fehlverhalten und der Bus-Treiber schaltet gar nicht. Ich vermute, dass da fürs Steckboard ein Treiber dazwischen muss, damit das Signal nicht durch die Längen und Übergänge nahezu verendet. Beim Dekoder blubbert es beim Zugriff an allen Ausgängen.


    Die Register bei 644p und 1284p lassen sich auch nicht aus den üblichen Tutorials übernehmen. Da haben die in den 380-500 Seiten Datenblättern ordentliche Register-Strukturen dokumentiert. Da musste ich erst mal durch, bis der IRQ überhaupt mal ausgelöst wurde. :)



    So schreibt es schon mal und gibt das Byte dann auf Port A aus. Wenn der AVR nicht angesprochen wird, geht der mit laufendem Oszillator in Standby. Funktioniert abgesehen von den technischen Ungereimtheiten soweit schon mal ganz gut.