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

last post from strik at the

C64 Tastatur "abfangen"

  • was heißt ohne Pull Device ? 🤔

    Meinst du keine interne Pull up Widerstande setzrn ?

  • Ich habe das bei mir auf dem Tiny mit PinChange Interrupt gelöst.


    Mfg Jood

    dein Plan schaut auf den ersten Blick so aus wie ich das jetzt machen würde.

    PinChange Interrupt klingt interessant.

    Hast du aber nur auf PA0, oder ?

    Ich müsste mal schauen wie ich das gelöst bekomme.

    Ich habe 3 PAs. Der Atmega 8 hat drei IRQs. Könnte gehen.

    Für ein anderes Projekt musste ich feststellen, dass 8Mhz Taktung noch zu lahm ist. Zumindest für Bascom. Da wollte ich was mit PLA machen 🙄

    Ich kann nur Bascom programmieren. Hatte mal mit Assembler versucht - aber da muss man ja das Rad neu erfinden.

    Für das, was ich bisher gemacht habe, reichte Bascom.

  • was heißt ohne Pull Device ? 🤔

    Meinst du keine interne Pull up Widerstande setzrn ?

    Habe schon seit zwanzig Jahren nichts mit mit Atmels gemacht, aber normalerweise kann man bei den meisten Mikrocontrollers Pull-Ups oder Pull-Downs konfigurieren, die aber im engeren Sinne keine echten Widerstände sind. Üblicherweise sind das sehr schwache Stromsenken/-quellen, aber sicherheitshalber sollte man sie trotzdem deaktivieren, damit sie den internen Keyscan o.ä. nicht stören können.

  • was heißt ohne Pull Device ? 🤔

    Meinst du keine interne Pull up Widerstande setzrn ?

    Habe schon seit zwanzig Jahren nichts mit mit Atmels gemacht, aber normalerweise kann man bei den meisten Mikrocontrollers Pull-Ups oder Pull-Downs konfigurieren, die aber im engeren Sinne keine echten Widerstände sind. Üblicherweise sind das sehr schwache Stromsenken/-quellen, aber sicherheitshalber sollte man sie trotzdem deaktivieren, damit sie den internen Keyscan o.ä. nicht stören können.

    ah, ok.

    Bei den Tiny und Atmega kann man interene Pullups setzen. Pull Down gibts da nicht.

    Das heißt wenn ich den setze kann ich ohne Probleme auf L abfragen, da ich ja ohne L ein definiertes H Signal habe.

    Ist bei der Tastaturmatrix dann ja Blödsinn, da ich über PB0 vom CIA das definierte H Signal habe. und auf L abfrage, da L vom PA0 kommt und über Taste durchgeschaltet wird. Richtig ? 🤔

  • PinChange Interrupt klingt interessant.

    Hast du aber nur auf PA0, oder ?

    Den interrupt habe ich auf PA0 und PA7, war eigentlich so gedacht das ich das Ende eine Keyboard Scans mitbekomme.


    Letztlich habe ich das aber recht primitiv gelöst, bei jedem Interrupt (Spalten) werte ich die Spalte aus und lese die Reihen ein.


    Interessant sind die Zeilen mit GIMSK und PCMSK1, der Kram danach ist nur Timerprogrammierung für die LED PWM,

    und dann weiter unten der interrupt-Handler (ISR(PCINT1_vect).


    Zumindestens in Arduino C ist das schnell genug!


    Mfg Jood


  • Arduino 😱

  • Bei den Tiny und Atmega kann man interene Pullups setzen. Pull Down gibts da nicht.

    Das heißt wenn ich den setze kann ich ohne Probleme auf L abfragen, da ich ja ohne L ein definiertes H Signal habe.

    Ist bei der Tastaturmatrix dann ja Blödsinn, da ich über PB0 vom CIA das definierte H Signal habe. und auf L abfrage, da L vom PA0 kommt und über Taste durchgeschaltet wird. Richtig ? 🤔

    Hm. Also wie gesagt würde ich davon abraten, die Pull-Ups zu setzen, wenn Du passiv scannen willst. Vermutlich ist es schnurz, weil das üblicherweise Ströme im Bereich von 20µA oder so sind, aber es besteht auch keinerlei Notwendigkeit, weil der CIA ja interne Pull-Ups hat. Das sieht man ja daran, daß im Datenregister eines auf Eingang konfigurierter PortB immer "0xff" steht (also alles Einsen).

    Und einen Low-Pegel an PortB kann es beim Keyscan des Kernals nur geben, wenn ein Pin von PortA gerade gegen Masse geschaltet ist und gleichzeitig eine Taste in der entsprechenden Spalte die Verbindung zur einer Zeile an PortB herstellt.

  • Wenn ich das richtig verstehe, dann muss entweder die Tastaturabfrage im C634 aktiv sein, oder das Gerät muss selber an den Spalten herumspielen und riskieren, evtl. das Programm zu stören.

    Wäre es da nicht besser, das mechanisch zu lösen und unter jeder der 3 F-Tasten einen eigenen zusätzlichen Taster anzukleben?

  • Also passiv kann man nur "mithören", wenn intern ein kompletter Scan läuft (also alle Pins von PortA zyklisch einzeln durchgeschaltet werden). Mit dem Kernal-Scan ist das auf jeden Fall möglich. Bei Spielen und Demos halt nicht unbedingt.

    Und einen aktiven Scan würde ich grundsätzlich nur zusammen mit Restore o.ä. machen. Also Restore gedrückt halten und eine Funktionstaste drücken, um den Kernal umzuschalten o.ä. Damit stört man den internen Scan wenn überhaupt nur während dieser kurzen Phase und das sollte in aller Regel kein Drama sein.

    Wenn man die Verbindung zwischen Tastatur und CIA per Analogschalter auftrennt (entweder alle 16 Leitungen, um ganz sicher zu gehen oder zumindest die von PortA für eine >90% Abdeckung), können keine falschen Tasten vom internen Scan erkannt werden. Er kann lediglich gerade gedrückte Tasten kurz nicht mehr erkennen. Aber in dem Szenario "Restore+Taste->Umschaltung" sollten ja eh keine anderen Tasten dauerhaft gedrückt sein.

    Und selbst wenn man Leitungen von PortA selber gegen Masse zieht, sollte es möglich sein, daß Timing so anzupassen, daß das den internen Scan nicht oder zumindest so wenig wie möglich stört.

  • Ich hab das ganze jetzt mal ausprobiert.

    Es funktioniert soweit, aber leider nicht richtig

    Möchte ich z.B "F1" abfragen ziehe ich PA0 und PB4 auf zwei Eingänge vom Mikrocontroller.

    Ich frage nun beide Pinne auf "0" ab.

    Drücke ich "F1" macht das Programm was es soll, leider auch bei allen anderen Tasten die auf PB4 mit hängen.

    Das wären Space, R-Shift, ".", M, B, C und Z.

    Kann mir da mal wer auf die Sprünge helfen ? 🤔

    Vlt. hab ich ja nicht richtig verstanden wie die Tastaturabfrage im Kernal bzw. $DC00/$DC01 funktioniert 🤷‍♂️

  • Drücke ich "F1" macht das Programm was es soll, leider auch bei allen anderen Tasten die auf PB4 mit hängen.

    Ich weiss nicht ob das wirklich hilft, aber das hier funktioniert, allerdings nutze ich auch PA0 & PA7!


    Ich nutze den PinChange Interrupt für die Reihen (PA0, PA7), bei jeder Änderung wird ISR(PCINT1_vect) angesprungen,

    dort wird dann die aktuelle Reihe geprüft und die Spalten verglichen.


    Abschließend setze ich nur die entsprechende Variable (volatile Kernal) und verlasse den Interrupt, die Auswertung erfolgt

    im Mainloop.


    Mfg Jood

  • Wie meine Messungen zeigen, werden bei den meisten Keyscans, speziell auch bei dem dem Kernals, zunächst alle PA-Pins nach unten gezogen.

    Die Kernal-Abfrage liegt ab $EA87.

    Das allererste, was passiert ist:


    Code
    1. EA87 LDA #0
    2. ..
    3. EA90 STA $DC00
    4. EA93 LDX $DC01
    5. EA96 CPX #$FF
    6. EA98 BEQ $EAFB
    7. ...

    D.h., er testet als allererstes alle Spalten. Wenn keine Aktiv ist ($DC01 hat $FF), dann überspringt er das Scannen der einzelnen Zeilen.


    Das dürfte auch der Grund sein, wieso Zak PA auf 0 hält, so kann es den ersten Schritt sparen und ist schneller.



    Ein Aspekt, den ich noch nicht hier gesehen habe: Was ist mit der Joystick-Abfrage? Die Joysticks hängen ja auch an PA und PB, das sollte sich nicht mit dem Scannen beissen.


    Zwischen $EA98 und $EAFB liegt dann die eigentliche Abfrage. Kurz: $FE --> $DC00, dann $DC01 lesen, entprellen (mit CMP) und testen, ob Bit 0 (per LSR in einer Schleife, d.h., die höchstwertigen Bits werden zuerst getestet). Wenn durch, dann $DC00 nach links shiften (SEC/ROL) und nächste Zeile probieren, bis alle 8 Zeilen durch sind. Das ist auch der Grund, wieso am Ende $7F in $DC00 stehen bleibt, das Ergebnis wird einfach nicht mehr angefasst.

  • Die Joysticks schließen Pins von PA und PB direkt gegen Masse kurz. Dazu müssen die entsprechenden Pins hochgezogen sein (was sie normalerweise ja fast immer sind). ButtonA geht auf PB4 - in dieser Zeile (row4) liegt auch Space.

    Wenn also gerade der Keyscan läuft und man Button A drückt, wird das als Space fehlinterpretiert. Das ist insofern ganz interessant, weil der Kernal eigentlich mit PA0 anfängt, Space aber in der Spalte (col7) PA7 liegt.

    Das liegt vermutlich daran, daß PA7 als letzte Spalte gescannt wird und PB4 die ganze Zeit low bleibt, solange man ButtonA drückt. Oder so.

  • Wie meine Messungen zeigen, werden bei den meisten Keyscans, speziell auch bei dem dem Kernals, zunächst alle PA-Pins nach unten gezogen.

    Die Kernal-Abfrage liegt ab $EA87.

    Das allererste, was passiert ist:


    Code
    1. EA87 LDA #0
    2. ..
    3. EA90 STA $DC00
    4. EA93 LDX $DC01
    5. EA96 CPX #$FF
    6. EA98 BEQ $EAFB
    7. ...

    D.h., er testet als allererstes alle Spalten. Wenn keine Aktiv ist ($DC01 hat $FF), dann überspringt er das Scannen der einzelnen Zeilen.

    Ähhhh....

    Sind die Spalten nicht $DC00 ?!

    Falls das im C64 WIKI passt. Habs auch schon anders rum gesehen. Weiß aber nicht was richtig udn was falsch ist 🤷‍♂️

  • Also im Schaltplan werden die PortA-Pins als "Column"/Spalte bezeichnet und die PortB-Pins als "Row"/Zeile.

    Aber im Prinzip ist die Nomenklatur egal. Ist halt eine Matrix.

    Sicher ist, daß PortA auf Masse geschaltet und auf PortB gemessen wird. Und PortA sollte bei $DC00 liegen.

    Das Schalten von PortA zeigen ja auch meine Messungen. Was noch aussteht, ist die Messung von PortB in einigen Sonderfällen.