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

letzter Beitrag von Wiesel am

PS2-Tastatur am C64

  • schwierig, es gibt auch scanner die mit verschiedenen mustern abwechselnd in beide richtungen scannen, damit kann man wohl diverse "ghostkey" probleme in den griff kriegen


    Damit bekommt man wirklich Ghostkey-Probleme in den Griff, aber auch nur die, die durch Joysticks verursacht werden. Ghostkeys innerhalb der Matrix erkennt man so nicht.


    Die Frage wäre, ob nicht eine automatische Erkennung der Richtung machbar ist: Die Matrix-Output-Routine lauscht so lange, bis einer der beiden Ports nicht mehr $ff ist. Je nachdem, welcher Port als Erster ungleich $ff ist, springt man in Richtungs-Routine A oder B. Problem: Richtungswechsel ist nur dann möglich, wenn die Abfrage-Routine auf C64-Seite auch brav auf $ff zurückschaltet und der Benutzer nicht gerade am Joystick rappelt.


    Jens


    (danke fürs back2topic)

  • Zitat

    Die Frage wäre, ob nicht eine automatische Erkennung der Richtung machbar ist: Die Matrix-Output-Routine lauscht so lange, bis einer der beiden Ports nicht mehr $ff ist. Je nachdem, welcher Port als Erster ungleich $ff ist, springt man in Richtungs-Routine A oder B. Problem: Richtungswechsel ist nur dann möglich, wenn die Abfrage-Routine auf C64-Seite auch brav auf $ff zurückschaltet und der Benutzer nicht gerade am Joystick rappelt.


    Oder Binärkomparatoren auf beiden Ports nutzen um einen Interrupt zu erzeugen? Allerdings klappt das auch nur wenn kein perfider Coder einzelne Bits der Ports wechselseitig benutzt.

  • Oder Binärkomparatoren auf beiden Ports nutzen um einen Interrupt zu erzeugen? Allerdings klappt das auch nur wenn kein perfider Coder einzelne Bits der Ports wechselseitig benutzt.


    ...und wenn man genau darüber nachdenkt, könnte man so sogar bestimmte Ghostkeys innerhalb der Matrix erkennen, ich muß also mein Posting von gerade korrigieren und das Gegenteil behaupten: Wenn man immer nur ein Bit als Ausgang schaltet und 15 Bits als Input auswertet, können auch bestimmte Ghostkey-Effekte als Solche erkannt werden.


    Als IRQ-Quelle müsste man eigentlich die Ports eines Microcontrollers so programmieren können, dass sie einen falling-edge-IRQ auslösen, also ganz ohne Zusatzhardware. Oder können das die 8-bit AVRs nicht?


    Jens

  • Zitat

    Wenn man immer nur ein Bit als Ausgang schaltet und 15 Bits als Input auswertet, können auch bestimmte Ghostkey-Effekte als Solche erkannt werden.


    oder - ähnlich wie bei der abfrage der shiftlock-taste - mit "ausgang-gegen-ausgang" o.ä. rumspielen .... ich meine da hat marko auch mal was gemacht in der richtung.

  • Als IRQ-Quelle müsste man eigentlich die Ports eines Microcontrollers so programmieren können, dass sie einen falling-edge-IRQ auslösen, also ganz ohne Zusatzhardware. Oder können das die 8-bit AVRs nicht?


    Wenn der AVR hinreichend neu ist (zB mega48/88/168, mega164/324/644, aber nicht mega16/32) kann man auf allen (kleinere Chips) bis einigen wenigen (mega1281 =( ) I/O-Pins Pin-Change-Interrupts aktivieren - die triggern allerdings leider immer auf beide Flanken und um herauszufinden welcher Pin eines Ports den IRQ ausgelöst hat muss man den aktuellen Zustand mit einem gespeicherten vergleichen.


    Für die Tastenmatrix-Abfrage sollte das allerdings kein Problem darstellen, auch wenn die Worst-Case-Interruptlatenzzeit beim AVR IIRC 6 Takte beträgt.

  • [font='&quot']Hallo Marduk,


    ich hatte auch schon ueberlegt mit einem Microcontroller vom Typ Picaxe 28X oder 40X die Matrix nachzubilden, da mein
    C128D keine Tastatur hat.


    Fuer einfache (richtig herum scannende) Programme wuerde ich sicherlich gehen...ich muesste in der Matrix nur die Shift und Doppelfunktionstasten
    sowie die LOCK-Tasten einbauen....sicherlich kein Ersatz fuer einen Matrix-IC, aber zumindest koennte man, wie wohl auch bei Deiner Idee, schon mal auf dem Geraet tippen....


    Der Picaxe hat beim 28X / 40X den Vorteil, dass er "nativ" eine PS/2 Tastatur unterstuetzt....
    Wenn daraus jemand eine kleine Platine macht mit dem Chip koennte man zu 1/4 bis 1/3 der sontigen Preise ein Tastatur-Interface Light bauen :-)


    Gruesse und Daumen hoch fuer die Idee :-)
    Guido
    [/font]

  • Für die Tastenmatrix-Abfrage sollte das allerdings kein Problem darstellen, auch wenn die Worst-Case-Interruptlatenzzeit beim AVR IIRC 6 Takte beträgt.


    Gerade gemessen: Der Abfrage-Impuls ist fast 40µs lang, das ist für nen Microcontroller von heute Spazierschritt. Und ne Idee, wie man ohne den teuren Matrix-Chip hinkommt, habe ich auch. Ne Lösung für das ShiftLock-Problem habe ich aber noch nicht, und für den 128er sollte man sich auch gleich was ausdenken, aber dafür fehlt mir die Zeit. Die Idee für einen Tastaturadapter gefällt mir aber, vielleicht mache ich ein Produkt draus.


    Jens

  • Ähm, bin vielleicht schon zu müde, um das zu raffen, aber: Wenn an den CIAs OC-Ausgänge sind oder sowas. Und man das am Atmel auch so machen würde. Kann man dann nicht stupide in beide Richtungen hin- und herschalten? Also A lesen, B schreiben, B lesen, A schreiben... Mhhh, nein. Sobald man auf lesen schaltet und im gleichen Moment die CIA auch liest, ist ja Mist.


    Aber vielleicht spinnt jemand die Idee weiter ;-)

  • Mhhh, nein. Sobald man auf lesen schaltet und im gleichen Moment die CIA auch liest, ist ja Mist.


    Ähemm.. nee, das ist nicht die Ursache. Vielmehr hast Du das Problem, dass auf ein- und derselben Leitung eine 0 stehen kann und Du nicht weisst, wer diese 0 erzeugt hat: Du selbst, oder der Computer per Abfrage. Wenn eine Ghostkey-Erkennungsroutine halbwegs intelligent programmiert ist, testet sie nur die Bits ab, die sie auf dem "Hinweg" auch gesehen hat. Wenn sie dann noch gemein programmiert ist, wird *nicht* zwischendrin auf $ff umgeschaltet, so dass Du keinerlei Möglichkeit hast, den Scan-Zeitpunkt zu erkennen.


    Selbst wenn Du Dir "merkst", dass Du gerade Bit X von Port B auf low gezogen hast hilft das nicht viel, weil gerade dieses Bit bei der Ghostkey-Erkennung interessant ist. Ein- und denselben Pin kannst Du an einem Microcontroller nicht zum Eingang und zum Ausgang machen; null ist null, aber die Quelle dieser Null zu ermitteln ist "beliebig schwer", denn Du hast drei mögliche Quellen: Joystick, CIA-Scan und Dich selbst.


    Ich denk' mir was aus, was ich vielleicht unter ner open-Hardware-Lizenz veröffentliche (Premiere, habbich noch nie gemacht). Ein Riesengeschäft wird das wohl kaum werden.


    Jens

  • Bevor ich Jens' Beitrag gelesen hab, hab ich selbst den Gedanken weitergesponnen.


    Das Ganze wird nicht portweise, sondern leitungsweise gemacht, dadurch kann jede Leitung einzeln in eine andere Richtung geschaltet sein. Ich gehe davon aus, dass, wenn ich an beiden "Enden" (Also Zeile oder Spalte) der Matrix eine 0 lese, sich eine gedrückte Taste nicht auswirkt. Wenn ich an einem Ende keine 0 mehr lese, wurde wohl gerade die Richtung auf dieser Leitung umgedreht und ich schalte das andere Ende auch wieder auf Input. Und ich gehe davon aus, dass Bits, die von der CIA gelesen werden und die ich nicht auf Low ziehe, auf High liegen.



    Die Hauptaufgabe dabei ist, die Daten so geschickt abzulegen, dass die ganze Schleife in wenigen µs durchlaufen kann. Da man manche Operationen meistens abkürzen kann und oft mehrere Leitungen bzw. Bits mit logischen Operationen auf einmal behandeln kann, sollte das klappen. Die Codegröße ist ja auch nicht sooo ausschlaggebend, weil der Controller sonst nichts zu tun hat.


    Nun muss ich zugeben, dass ich nur ahne, was eine Ghostkey ist und keinen Schimmer habe, wie sie normalerweise detektiert werden. Deshalb weiß ich auch nicht, ob und warum dieser Algorithmus nicht immer funktionieren würde.


    Aber immerhin könnte man eine Menge verquerer Tastaturabfragen mit einem primitiven Controller unterstützen. Auf IRQs würde ich ggfs. sogar verzichten. Den Overhead könnte man sich wahrscheinlich sparen, wenn das PS2-Protokoll wirklich so langsam ist, dass man es in der Hauptschleife mit abfrühstücken könnte.


    Hinweis: Leitungen, die auf Eingang stehen und immernoch auf Low sind, rufen bei unveränderter Tastensituation keine Änderung am anderen Ende hervor.
    Hin- und Hergeschaltet wird vom Controller aus natürlich immer nur Input<=>Low.


    Wenn ihr erkennt, dass mit dieser Lösung etwas definitiv nicht funktioniert, bitte schreibt ein ganz konkretes Beispiel. Das vermeidet Missverständnisse.


    Gruß,


    Thomas

  • Zitat

    Nun muss ich zugeben, dass ich nur ahne, was eine Ghostkey ist und keinen Schimmer habe, wie sie normalerweise detektiert werden. Deshalb weiß ich auch nicht, ob und warum dieser Algorithmus nicht immer funktionieren würde.


    wenn du auf der tastatur mehrere tasten gleichzeitig drückst (oder gleichzeitig am joystick wackelst, was aber ja prinzipiell das gleiche ist) gibt es - je nach tasten - kurzschlüsse in der matrix und ein herkömmlicher scanner erkennt dann tasten die garnicht gedrückt sind - die ghostkeys.

  • Gut, so ähnlich habe ich es geahnt. Der zweite Teil der Antwort fehlt aber noch :-)


    Okay, ich habe noch nicht genau darüber nachgedacht, was mit der o.g. Implementierung passiert, wenn ein Joysticks-Kontakt geschlossen ist. Bis jetzt würde das so gewertet werden, als sei die entsprechende Leitung der CIA auf Low. Wir würden also, falls eine Taste gedrückt ist, das andere Ende der Matrix auch auf Low ziehen (wenn es nicht schon von der CIA auf Low ist). Sobald der Joystick-Kontakt geöffnet würde und die entsprechende Leitung nicht auch von der CIA auf Low liegt, würden wir auch das andere Ende wieder loslassen (also auf Input schalten). Ist doch eigentlich wie bei einer physikalischen Tastatur, die "weiß" auch nicht, ob die CIA oder der Joystick an der Leitung zieht.


    Und wenn Du jetzt noch sagst, warum sich ein ghostkey-aware Scanner an o.g. Implementierung stören würde. Ich seh's wirklich nicht.

  • öhm.... der zweite teil ist schwieriger zu erklären.... da gibts mehrere ideen die oft kombiniert werden:


    - schlichtes scannen in die andere richtung. (zur unterscheidung joystick/tasten reicht das glaub ich)
    - scannen mit verschiedenen bitmustern, und eventuell auch sogar mit in verschiedene richtungen eingestellten leitungen auf dem selben cia port
    - ausnutzen von dreckeffekten, zb paar takte lang ausgang gegen ausgung treiben, dann im scanner die latches lesen. hier kann man durch messen der zeit bis ein bit kippt rückschlüsse darauf ziehen was in der matrix passiert (ähnlich wie bei der abfrage von shift-lock)


    letzteres würde ich vermuten ist schwierig bis garnicht zu simulieren mit so einer schaltung (egal welcher art).

  • Danke für die Infos.


    - schlichtes scannen in die andere richtung. (zur unterscheidung joystick/tasten reicht das glaub ich)


    Das sollte mit o.g. Methode gehen. In dem Moment, wo die CIA den zuvor von ihr benutzten Ausgang auf Eingang umschaltet, bekommen wir das mit und ändern auch die Richtung. Dazu muss die Schleife wie o.g. schnell genug durchlaufen (vor dem nächsten Lesen (4 µs?) muss alles erledigt sein), sonst klappt's nicht.


    Einen Joystick sollte man sogar noch einfacher erkennen können: Wenn die CIA alle Ports auf Input hat und totzdem noch irgendwo ein Low reinkommt.


    Zitat

    - scannen mit verschiedenen bitmustern, und eventuell auch sogar mit in verschiedene richtungen eingestellten leitungen auf dem selben cia port


    Sollte auch berücksichtigt sein, weil wir pro Leitung und nicht pro Port arbeiten.


    Zitat

    - ausnutzen von dreckeffekten, zb paar takte lang ausgang gegen ausgung treiben, dann im scanner die latches lesen. hier kann man durch messen der zeit bis ein bit kippt rückschlüsse darauf ziehen was in der matrix passiert (ähnlich wie bei der abfrage von shift-lock)


    Obwohl ich das Prinzip noch nicht ganz verstehe (Ausgang gegen Ausgang bei OC?): Das hat wohl was mit den unterschiedlichen Widerständen von Shift Lock und Shift zu tun. Und funktioniert wohl nicht mal auf allen C64igen zuverlässig.


    Zitat

    letzteres würde ich vermuten ist schwierig bis garnicht zu simulieren mit so einer schaltung (egal welcher art).


    Wenn man wirklich eine Primitivlösung mit einem Controller und sonst nix umsetzen möchte, könnte man auch darauf verzichten. Selbst ein Matrixschalterdingens wird das vermutlich nicht ohne weiteres können.


    Eigentlich habe ich auch keine Zeit, mich mit diesem Thema zu beschäftigen. Aber interessant ist's und ich schaue auch wiedermal vorbei :-)

  • In dem Moment, wo die CIA den zuvor von ihr benutzten Ausgang auf Eingang umschaltet, bekommen wir das mit und ändern auch die Richtung. Dazu muss die Schleife wie o.g. schnell genug durchlaufen (vor dem nächsten Lesen (4 µs?) muss alles erledigt sein), sonst klappt's nicht.


    Es klappt auch so nicht. Folgendes Szenario:


    - Scanner setzt Port A auf %11111110
    - Microcontroller bekommt's mit und errechnet %11110111 für Port B - wird ausgegeben


    Bis hierhin kein Problem - die Taste wird gedrückt. ABER: Wenn jetzt eine Ghostkey-Routine ihrerseits Port B auf Ausgang schaltet und auf %11110111 legt, aber dann erst Port A auf Eingang schaltet, steht auf beiden Seiten die 0, ohne dass Du herausfinden kannst, wer welchen Pin auf 0 gezogen hat. Irgendwann geht Port A dann auf $ff, weil dort nach Input gesucht wird, woraufhin Du erst reagieren kannst - möglicherweise zu spät, denn die Ghostkey-Routine hat schon gesagt "oh, da ist ff, also wurde doch nichts in dieser Spalte gedrückt".


    Schlimmer ist, wenn mit Port A gescannt wird und an Port B am Joystick gewackelt wird, denn dann fehlt Dir jede Info darüber, welches Bit in welche Richtung geht. Du mußt also auch die Situation abdecken, die annimmt, dass sowohl in Port A, als auch in Port B einzelne Bits auf Ausgang gestellt sind. Ohne Kenntnis der beiden DDRs ist das schlicht und einfach nicht möglich. Du wirst immer nur eine Teilmenge an Scannern und Fällen abdecken, aber mir erschließt sich kein Weg, wie Du *alle* Fälle in Betracht ziehen kannst.


    Du wirst also immer Annahmen über den Scanner machen müssen - schlechte Idee für universal-Hardware.


    Jens

  • Irgendwann geht Port A dann auf $ff, weil dort nach Input gesucht wird, woraufhin Du erst reagieren kannst - möglicherweise zu spät, denn die Ghostkey-Routine hat schon gesagt "oh, da ist ff, also wurde doch nichts in dieser Spalte gedrückt".


    Danke für das konkrete Beispiel. Kann die Routine denn aus Port A lesen, ohne dort auf Eingang umgeschaltet zu haben?


    IMHO kann sie erst den anderen Port aus Schreiben schalten. Irgendwann muss sie aber den Port A (evtl. nur diese Leitung) auf Input schalten. Diese wird dann aus Sicht des Controllers high (1). Jetzt sorgt die Schleife dafür, dass die Richtung umgeschaltet wird. Mit der nächsten Instruktion liest die CIA das Register aus. Schließlich kann auch die CIA auf einer Leitung nicht gleichzeitig schreiben und (was anderes) lesen. Da sollte das seitens des Controllers dann schon erledigt sein. Deshalb kam ich ja auch auf 4 µs (STA DDRA, LDA DRA oder sowas). Wobei es evtl. auch nur 3 sind, wg. der CIA.


    Über Deinen zweiten Absatz denke ich nach, wenn wir den Irrtum im ersten geklärt haben. Egal, auf welcher Seite er liegt ;-)


    (1) Denn diese Seite/Leitung habe ich ja genau aus diesem Grund im Controller als Input gelassen.


    Edit:

    Zitat

    steht auf beiden Seiten die 0, ohne dass Du herausfinden kannst, wer welchen Pin auf 0 gezogen hat


    Das ist meiner Meinung nach der Irrtum: Die 0 steht nicht (dauerhaft) auf beiden Seiten. Sie verschwindet auf der Seite, von der kurze Zeit später gelesen werden soll. Aber vielleicht liege ich ja hier auch falsch. Dann lerne ich gern was dazu.

  • Kann die Routine denn aus Port A lesen, ohne dort auf Eingang umgeschaltet zu haben?


    Ja. Das ist ja das, was Sauhund ständig als "Ausgänge gegeneinander treiben" bezeichnet (so fragt man linke shift und shift-lock getrennt voneinander ab). Beim Auslesen des Datenregisters wird nicht das zurückgegeben, was man reingeschrieben hat, sondern das, was wirklich am Port anliegt. Wenn eine 1 reingeschrieben wurde, aber ein Kurzschluß gegen GND anliegt, liest man wirklich eine 0 zurück, trotz "Ausgang"-Programmierung im DDR.


    Jens

  • Ah, verstehe, dass wusste ich nicht.


    Mhh, es scheint aber nichts an meinem letzten Beitrag zu ändern: Statt von Output auf Input umzuschalten und uns damit Reaktionszeit zu gönnen, müsste der "Leser" von 0 auf 1 umschalten und dann lesen, was uns auch Reaktionszeit gibt.


    Zugegebenermaßen ist das Thema für mich nur akademisch, weil ich nicht vorhab, sowas zu machen. Und der Thread-Starter hat sich anscheinend schon ausgeklinkt. Könnte auch ziemlich sportlich werden, wenn man das mit einem Atmega lösen wollen würde, wenn man wirklich nur 3 µs zum Durchkauen der Logik hat. Ich würde ja einen LPC2101 nehmen ;-) Aber den kann wieder keiner löten. Oder gleich programmierbare Logik.


    Es gibt aber definitiv eine theoretische Lücke im o.g. Code: Mehrere gedrückte Tasten. Was aus der einen rauskommt, würde sich rückwärts wieder auf den "Quellport" auswirken. Bei Shift z.B. ginge es noch, aufgrund der Anordnung in der Matrix. Da wird kein Rückwärts gebraucht. Aber mehrere Buchstaben z.B....

  • Hallo,


    wollte mal 'nen neuen Denkanstoss hier rein bringen. :juhu:
    Ist zwar extrem aufwändig meine Idee, aber wie folgt wäre man dann auf der sicheren Seite: Statt die Matrix in einem Microcontroller dekodieren und steuern zu wollen, muss man halt wirklich das nachbilden was die Tastatur macht. Sprich 64 ansteuerbare Taster nachbilden (Stichpunkt wäre bidirektionaler Schalter). Denn die Tastatur ist nunmal eine passive Matrixschaltung. Diese 64 Schalter könnte man dann über ein bzw. mehrere Schieberegister bedienen.
    Was kriminell an dieser Idee ist, ist der Verschaltungsaufwand. Obwohl auch nicht; bei einer Doppelseitigen Platine würde die eine Seite die Matrix der Tastatur führen u. die andere Seite die Ansteuerungsleitungen. Als Schalter hab' ich auf die Schnelle den 74HC4066 (Quad bilateral switches) gefunden. Bräuchte halt 16 Stück von den Dingern. Oder was vergleichbares.
    Was haltet ihr von der Idee? ?(


    Gruß,
    therealdrcreep