Hello, Guest the thread was called1.4k times and contains 54 replays

last post from strik at the

C64 Tastatur "abfangen"

  • Mahlzeit....

    Für ein Projekt möchte ich gerne z.B. die Tasten "F1", "F3" und "F5" unabhängig von einem laufenden Programm abfragen, bzw. mit einem Atmega8 auswerten.

    Damit nichts hochgehen kann soll das ganze galvanisch getrennt funktionieren.

    Ich hab mal was zusammengekritzelt.

    Für diesen Fall soll "F1" abgefragt werden.

    Da F1-F7 an PA0 dran hängt und die CIA Ports nicht großartig belastet werden dürfen soll das über ein 74LS241 IC laufen.

    Wenn ich es richtig verstanden habe ist beim CIA, bzw. bei der Tastaturabfrage (Kernal) der PortA auf Ausgang und der PortB auf Eingang geschaltet.

    Hat der PortB in diesem Fall interne Pullups ? Oder wie funktioniert das ?

    Ich hab schiss den PortB so zu grillen bei dem was ich aufgemalt habe.

    Theoretisch müsste es so aber funktionieren.

    Die Tastatursbfrage im Kernal setzt - wenn ich es richtig verstanden habe - nacheinander jeweils PortA Bit 0-7 auf High und fragt gleichzeitig ab ob an PortB Bit 0-7 jeweils ein High Signal aufläuft, also quasi durch einen Tastendruck durchgeschaltet wird.

    In meinem Fall wäre das für "F1" PA0 + PB4. Wenn beide High Signal haben schalter der Optokoppler durch und gibt mir ein Low Signal auf den Atmega8.

    Funktionieren sollte das so, aber bleibt der CIA Baustein auf Dauer am leben 🤔

  • das gibt's doch schon in fertig: keyman64


    EDIT:

    Die Optokoppler würde ich am "Schaltausgang" des Keyman platzieren.

    schau dir auch mal das Datenblatt des MT8808 an, der ist für solche Matrix-Aufgaben genau das Richtige !


    Alles OpenSource !

    Da das Teil direkt zwischen Tastatur und Mainboard liegt, kannst Du damit alles an Tastenkombinationen abfangen, was Dir beliebt.

    Durch die sehr gute Dokumentation lässt sich das wohl auch für eigene spezielle Sachen umstricken.

  • PS: weiß nicht ob der Line Drive da so wie er verbaut wurde viel bringt, weil er ja auch einen ZUSÄTZLICHEN Eingang darstellt. Ob das nur der Driver oder direkt ein Logikchip ist, ist doch wumpe. Der Treiber treibt ja nur die kleine Leitung bis zum Logikchip.


    Sinvoller wäre es, wenn die originale Leitung aufgetrennt, dann der Treiber eingesetzt und danach erst verzweigt wird, damit das getriebene Signal aufgeteilt wird

  • Ich hab ähnliches für einen PET aufgebaut, da hängen 7432 direkt an den Row- und Column-Leitungen und reagieren damit auf diverse Kombinationen (als Resetschalter und als Umschalter für Write Enable zweier Soft-Roms.

    Interessant. Gibt es dazu einen Schaltplan?

  • Moin,


    kein Ahnung ob dir das hilft, aber etwas ähnliches mache ich bei meinem Tiny Reset.


    Allerdings werte ich nur die Tasten F1, F3, F5 und F7 aus und nutze das als Kernalswitch

    ind Verbindung mit Restore.


    Schaltplan: TR84-Rev.1c.pdf


    Mfg Jood

  • Da ich selber eine ähnliche "externe" Tastaturabfrage plane, habe ich mir dazu ein paar Gedanken gemacht. Tatsächlich ist es so, daß der Kernal und die allermeisten Spiele PortA als Ausgang konfigurieren und PortB als Eingang. Beim Kernal wird dann eine 0 durch PortA geschoben und dabei jeweils PortB ausgewertet. Wie in dem anderen Thread diskutiert, kann man sich aber nicht unbedingt darauf verlassen, daß das in jedem Spiel und in jeder Demo auch so ist. Ein Spiel oder eine Demo könnte (in bestimmten Situationen) gar keinen Keyscan durchführen oder nur für bestimmte Spalten PAx). Und natürlich könnte man theoretisch auch PortB als Ausgang konfigurieren und PortA als Eingang. Habe ich zwar noch nicht gesehen, aber ich habe auch nur ein Dutzend Spiele geprüft.


    So oder so ist ein passiver Keyscan beim C64 problematisch. Selbst beim Kernal ist die Konfiguration außerhalb des IRQs so, daß nur PA7 auf Masse gezogen wird. Also kann man nur die entsprechenden Tasten der Matrix erfassen (1 bis Stop).

    Port A: 7f DDR: ff

    Port B: ff DDR: 00


    Für die Funktionstasten muß aber PA0 auf low gezogen sein, wenn man auf die übliche Richtungseinstellung vertraut. Also müßte man quasi darauf warten, daß PA0 gegen Massen gezogen wird und dann sehr schnell und synchron (im Bereich einiger Mikrosekunden) die Werte von PB0 erfassen, damit sie zu diesem Low-Pegel passen (und nicht zu dem von PA1 o.ä.).


    Aus meiner Sicht ist es für Kernalumschalter usw. deshalb zielführender, einen aktiven Scan zu machen. Um es 100% für die ganze Tastatur unter allen Bedingungen machen zu können, müßte man die Tastatur komplett von den CIAs trennen (16 Analogschalter), in fast allen Fällen würde aber wohl das Wegschalten von PortA (8 Analogschalter) reichen. Aber wie gesagt: es mag einzelne Spiele geben, die PortB auf Ausgang schalten.


    Wenn es einem nur um die Funktionstasten (und Cursortaste, Return, Del) geht, müßte es aber auch einfacher gehen. Mein Plan ist, bei längerem Drücken von Restore einen eigenen Mini-Keyscan zu machen, indem ich PA0 kurz (extern) auf Masse ziehe und dann die Pegel von PortB einlesen. Solange in diesem Augenblick nur eine der gewünschten Tasten (Funktionstasten usw.) gedrückt ist, müßte man die sicher erkennen können, auch wenn gerade noch eine oder mehrere andere Spalten auf Masse gezogen werden.

    Das externe Ziehen auf Masse geht, weil die CIAs keine Push-/Pull-Ausgänge haben, sondern Open-Collector-Ausgänge mit internen Pullups. Wichtig ist halt, daß man für das Schalten von PA0 selber nur gegen Masse schaltet (Lowside-Treiber, Open-Drain bzw. Open-Collector-Ausgang).
    Natürlich könnte das Drücken einer Taste während des eigenen Keyscans bei einem parallel laufenden internen Keyscan zu einer Fehlerkennung führen. Eventuell kann man das unterbinden, indem man sich mit dem internen Keyscan sychronisiert, indem man zum Beispiel PA0 überwacht und den eigenen Keyscan zwischen zwei Durchläufe des internen Keyscans legt.

    Das ist aber derzeit noch Theorie. Leider fehlt mir derzeit der I/O-Expander, um meine Schaltung aufzubauen.

  • Ich hab wenig Ahnung von Elektronik und hab ne Frage zu meinem Verständnis:

    Ist eine Elektronik, die Spannung messen soll, nicht generell "hochohmig", weil sie sonst die Spannung verändern würde?

    So ganz naiv müsste man ja PA0 und PB4 bis PB6 mit Masse vergleichen und das Ergebnis verANDen, oder?

  • Nochmal zur Verdeutlichung: es gibt Spiele, bei denen der gesamte PortA die meiste Zeit (zwischen den IRQs) auf Masse gezogen ist. Zum Beispiel Zak McKracken / Maniac Mansion:

    Port A: 00 DDR: ff

    Port B: ff DDR: 00

    Zwar ist auch hier wie üblich PortA auf Ausgang konfiguriert (DDR=0xff) und PortB auf Eingang (DDR=0x00). Allerdings sind alle Datenbits von Port auf 0 gesetzt, also sind alle Leitungen von PortA auf Masse gezogen. In diesem Zustand kann man eine Taste nicht mehr eindeutig identifizieren. Wenn also PB4 in diesem Zustand ebenfalls low ist, kann das von F1 (PA0), aber auch Z, C, B, M, ".", ShiftRight oder Space kommen.

  • mir würde es im Prinzip reichen wenn die Tastenabfrage im "Leerlauf" funktionieren würde. Also direkt nach einschalten, oder RESET.

    Wie genau macht es denn das Kernal ?

    Bei PA0 die Bits nacheinander auf HIGH ?

    und bei PB0 auf 1 abfragen ?

    oder wird auf 0 abgefragt ? Also all PAO die Bits nacheinander auf 0 ?

    Ich hab irgendwo gelesen, das auf 1 abgefragt wird. Stimmt das ?

  • Gibt es einen Grund, warum das gemacht wird?

    Ich habe ja die Spiele ja nicht tiefgehend analysiert, sondern mit nur kurz bei einem Dutzend Spielen oder so die Werte der Port-Register zwischen zwei IRQs angeschaut. Ich vermute aber mal, daß das halt der Wert ist, der am Ende des Keyscans des Spiels im Datenregister von Port A stand und man ihn so stehen gelassen hat. Im Kernal wird die 0x7f am Ende des Keyscans explizit auf PortA geschrieben, um die Abfrage der Stop-Taste auch außerhalb des eigentlichen Keyscans zu ermöglichen oder sowas in der Art. Das ist in diesem Fall also wohl kein zufälliger Wert.


    Man könnte sich auch vorstellen, daß man mit einer 0 in PortA ohne expliziten Keyscan sehen kann, ob irgendeine Taste gedrückt wurde (PortB != 0xff). Also könnte man den Wert zyklisch abfragen und bei Bedarf (irgendeine Taste wurde gedrückt), einen expliziten Keyscan starten.

    Was genau der Grund dafür bei den Lucasfilm-Adventures ist, kann ich aber nicht sagen. Andere Spiele von Lucasfilm verhalten sich wieder etwas anders:


    The Eidolon

    Port A: df DDR: ff

    Port B: ff DDR: 00


    Koronis Rift

    Port A: ff DDR: ff

    Port B: ff DDR: 00

  • Wie genau macht es denn das Kernal ?

    Bei PA0 die Bits nacheinander auf HIGH ?

    und bei PB0 auf 1 abfragen ?

    oder wird auf 0 abgefragt ? Also all PAO die Bits nacheinander auf 0 ?

    Ich hab irgendwo gelesen, das auf 1 abgefragt wird. Stimmt das ?

    Der Keyscan des Kernals passiert im IRQ. PortA wird auf Ausgang und PortB auf Eingang konfiguriert, dann wird eine Null durch PortA geschoben und PortB nach jedem Schritt geprüft.

    Die Ausgänge der CIAs können nur gegen Masse schalten (0). Im ausgeschalteten Zustand (1) wird der Pegel von einem Pullup hochgezogen. Wenn man eine Null auf PAx schreibt und eine Taste in dieser Spalte gedrückt ist, wird das entsprechende Bit PBx zu 0.

    Am Ende des Keyscans wird wie vorher beschrieben eine 0x7f nach PortA geschrieben. Damit ist nur PA7 low und nur Tasten in dieser Spalte können erkannt werden.


    Ich denke, das hier müßte der relevante Ausschnitt des Kernal-Keyscans sein:

  • ok, danke 😀

    Dann stimmt das nicht was ich gelesen habe.

    Magic Disk CIA Kurs.

    Ich hatte das auch so in Erinnerung wie du geschrieben hast. Zudem hatte ich es an anderer Stelle auch so gelesen.

    Die Spalte, die man haben will wird auf 0 gesetzt und B-Register wird dann auf 0 abgefragt.

    Dann muss ich meinen Kram nochmal überarbeiten....

  • Also wenn Dich nur der Keyscan des Kernals interessiert und nur die Spalte PA0, wäre es vermutlich tatsächlich eine Lösung, zum Beispiel PA0 und PB4 per ODER zu verknüpfen und auf eine Null am Ausgang zu reagieren. Das mit dem Optokoppler usw. halte ich allerdings für etwas übertrieben.

    Mit einem entsprechenden Mikrocontroller könnte man sicherlich auch einen DMA-Transfer eines ganzen IO-Ports (der mit PortB verbunden ist) an einer fallenden Flanke von PA0 triggern. Aber wie gesagt: in Spielen usw. könnte es mit diesem Ansatz zu Reaktionen auf falsche Tasten kommen.

  • ich brauche 3 PA und 6 PB.

    F1, F3, F5, die jeweils mit +/- reagieren und Shift (links)

    0xdeadbeef

    Meinst du ich könnte einfach jeweils parallel zu den PAs und PBs am CIA direkt auf den Atmega 8 gehen, ohne dass der CIA abraucht ?

    Das wäre natürlich das einfachste.

    Könnte dann die Ausgänge am Atmega galvanisch trennen - wenn ich es überhaupt benötige.

  • Also wenn Du die Pins am ATMega auf Eingang ohne Pull Device konfigurierst, sehe ich da eigentlich keine Probleme. Das plane ich bei meinem Projekt auch so zu machen. Also nicht mit einem Atmel, aber direkt Eingangspins eines Mikrocontrollers an die CIA-Pins anschließen.

    Ich glaube nicht, daß an dieser Stelle jemals jemand eine galvanische Trennung gemacht hat oder daß die nötig wäre. Der CIA ist ja nicht aus Zucker. Er hat halt nur wie die ganzen ICs aus dieser Zeit keine integrierten Klemmdioden und ist deshalb anfällig für elektrostatische Spannungen.


    Wie gesagt habe ich sogar vor, einen Schritt weiterzugehen und PA0 aktiv gegen Masse zu ziehen, damit ich in fast jeder Situation die Tasten in der Spalte PA0 scannen kann.

    Dir sollte aber klar sein, daß die Phasen, in denen PortA während des Scannens ein bestimmtes Bitmuster hat, nicht wahnsinnig lang sind. Habe das nicht ausgemessen, aber ich fürchte, daß das u.U. nur ein paar Dutzend (?) Mikrosekunden sind.

    wenn das in einem Interrupthandler passieren soll, müßte der schon auf der höchsten Priorität laufen und nichts machen, als die Werte wegzuschreiben.