Kleiner Maustreiber

Es gibt 41 Antworten in diesem Thema, welches 14.707 mal aufgerufen wurde. Der letzte Beitrag (13. August 2021 um 16:09) ist von WebFritzi.

  • Mir ist gestern nach dem Testen eingefallen, daß ich in meinem Brotkasten ja derzeit einen ArmSID verbaut habe. Nur um sicherzugehen, habe ich den Test inzwischen nochmal mit einem Shortboard mit echtem SID wiederholt, aber das Verhalten ist identisch. Der ArmSID bildet die PotX/Y-Erfassung also anscheinend recht genau ab.

  • Ich vermute, daß Vice die PotX/Y-Eingänge des SID nicht wirklich detailliert simuliert, sondern nur die Stellung des Multiplexers berücksichtigt.

    Das wird dann wahrscheinlich so sein, ja. Vielen Dank für deine Erklärungen.

    Mann, ich hoffe echt, meine Maus ist bald da. Warte darauf nun schon seit drei Tagen. Es ist nämlich auch so, dass die Maus in Vice sehr schnell und unruhig ist und man beim Klicken genau aufpassen muss. Hoffe, das ist auf echter Hardware anders.

    Beim aktuellen Vice 3.5 nightly läuft die Maus-Emulation an Port 2 bei mir schon mal gar nicht.

    Bei VICE 3.2 flitzt die Maus in der Tat viel zu schnell, aber in den Mouse Settings kann man die Sensivity von 40 auf 10 oder 5 senken, wobei 5 da einer echten 1351 am nächsten kommt.

  • Beim aktuellen Vice 3.5 nightly läuft die Maus-Emulation an Port 2 bei mir schon mal gar nicht.

    Das ist interessant. Danke. Ich bin jetzt aber eh auf Port 1 umgestiegen, da mich eventuelle Tastatureingaben bei meinem Spiel nicht stören.

    Bei VICE 3.2 flitzt die Maus in der Tat viel zu schnell, aber in den Mouse Settings kann man die Sensivity von 40 auf 10 oder 5 senken, wobei 5 da einer echten 1351 am nächsten kommt.

    Auch danke dafür. VICE 3.2 habe ich nicht, aber in VICE 3.5 sehe ich keine Möglichkeit, die Maussensitivity einzustellen.

    Bitte melde dich an, um diesen Link zu sehen. (Bitte melde dich an, um diesen Link zu sehen.)Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.
  • Wählt man beim VICE 3.5 r40486 die 1351 auf Port 2 steht danach in den Control Port Settings auch bei Port 1 die 1351.

    Aktiviert man mouse grab rührt sich nix. Ja, die Sensivity ist nicht vorhanden, wohl mit GTK3 verschütt gegangen. ;)

  • Wählt man beim VICE 3.5 r40486 die 1351 auf Port 2 steht danach in den Control Port Settings auch bei Port 1 die 1351.

    Interessant. Ich habe die Version r39984, und da ist das anders. Da kann ich die Maus auch nur über Input Devices -> Control Port auswählen. Ich kann dann einstellen, was ich in Port 1 und Port 2 haben will. Dort hatte ich Port 2: 1351 und Port 1: none ausgewählt, und das Programm auf der Testdisk lief.

    Bitte melde dich an, um diesen Link zu sehen. (Bitte melde dich an, um diesen Link zu sehen.)Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.
  • Ich hatte immer wizballs Solitaire probiert. Mit SDL2VICE r40486 funktioniert es hier. Aber auch da wurde die Mouse Sensivity wegrationalisiert.

    Wollte auch nochmal ein älteres GTK3VICE probieren, die vorherigen hatte ich die Woche erst von der Platte gefegt. :)

    edit: ah, hatte doch noch die reguläre 3.5er drauf, da geht die Maus auch.

  • Die 4-Millisekunden-Warteschleife sollte sich eliminieren lassen, indem 'über' dem ursprünglichen IRQ-Stackframe (Y,X,A,P,PC) ein Dummy-Stackframe angelegt wird, der in eine Nachbehandlungs-Routine im Maustreiber verweist.

    Der Maustreiber macht zuerst sein Ding (mit bereits korrekt eingestelltem Port-Multiplexer!), legt dann den Dummy-Stackframe an und kehrt zum KERNAL-IRQ zurück. Der KERNAL-IRQ macht die Tastaturabfrage und sonstiges Gedöns und hebt zum Schluß den Dummy-Stackframe ab - womit die CPU aber zunächst nicht beim Hauptprogramm weitermacht, sondern beim "Rest" des Maustreibers! Dieser Rest stellt dann noch den Multiplexer wieder auf den gewünschten Port und hebt dann den echten IRQ-Stackframe ab. Bis zum nächsten IRQ sind es dann 16 Millisekunden - lange genug, daß auf jeden Fall wieder gültige Werte in den POT-Registern stehen.

    POKEd jemand böswilligerweise das Portregister um, kein Problem: das steht nach dem nächsten Interrupt wieder richtig.

    Das Statusregister im Dummy-Stackframe sollte übrigens das I-Bit gesetzt haben. Weiß wer, warum? :D

  • indem 'über' dem ursprünglichen IRQ-Stackframe (Y,X,A,P,PC) ein Dummy-Stackframe angelegt wird, der in eine Nachbehandlungs-Routine im Maustreiber verweist.


    Der Maustreiber macht zuerst sein Ding (mit bereits korrekt eingestelltem Port-Multiplexer!), legt dann den Dummy-Stackframe an und kehrt zum KERNAL-IRQ zurück.

    Kapiere ich nicht. Was heißt "über"? Und wie "legt man" einen Stackframe "an"? Einfach ein paar Bytes in den Speicher schreiben? Und dann?

    wizball6502 hat in einem anderen Thread übrigens eine Lösung per Raster IRQ gefunden.

    Bitte melde dich an, um diesen Link zu sehen. (Bitte melde dich an, um diesen Link zu sehen.)Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.
  • Und wie "legt man" einen Stackframe "an"?

    Von Hand, mit PHA und PHP.

    Der Stackframe muß dann genau den gleichen Aufbau haben wie sonst auch beim Eintritt in die IRQ-Routine ab ($0314): die CPU hat bereits den PC und das Statusregister abgelegt, der KERNAL-IRQ-Handler legt noch A, X und Y dazu.

    Bei der Rückkehr aus dem Interrupt holt die Routine ab $EA81 das A, X und Y-Register wieder ab, RTI dann das Status-Register und den PC.

    Den Dummy-Stackframe "fabriziert" man jetzt so, daß der im Zwischengang aufgerufene Tastaturinterrupt bei dessen "Verwendung" in $EA81 nicht direkt zum Hauptprogramm zurückkehrt, sondern zu einer anderen vorgegebenen Stelle - eben dem "Rest" des Maustreibers! Wenn der dann fertig ist und seinerseits $EA81 aufruft, wird der ursprüngliche Stackframe abgehoben und dann erst geht's im Hauptprogramm weiter.

    Der Ablauf ist also jetzt so:

    1. Hauptprogramm läuft,
    2. Interrupt passiert,
    3. Maustreiber liest POT-Register und aktualisiert Mauszeiger,
    4. Maustreiber legt Dummy-IRQ-Stackframe an,
    5. Maustreiber springt zu $EA31 (bzw. "zu vorherigem Besitzer des IRQ-Vektors"),
    6. $EA31 ff. macht sein Interrrupt-Processing (Tastatur, Uhr, ...),
    7. Ende der IRQ-Routine bei $EA81 hebt Dummy-IRQ-Stackframe ab (!!!),
    8. "Rest" des Maus-Treibers wird ausgeführt und stellt Portregister für Multiplexer richtig ein,
    9. Maustreiber springt $EA81 an,
    10. $EA81 hebt jetzt originalen IRQ-Stackframe ab,
    11. Hauptprogramm läuft weiter.

    wizball6502 hat in einem anderen Thread übrigens eine Lösung per Raster IRQ gefunden.

    Ich denke nicht, daß die Verwendung eines Raster-IRQs an dieser Stelle für die Lösung des Portproblems relevant ist. Man wird ohnehin sinnvollerweise den Raster-IRQ anstelle des Tastatur-(CIA)-Interrupts verwenden, damit die Sprite-Register des Mauszeigers sauber "im Frame" geändert werden.

  • Wählt man beim VICE 3.5 r40486 die 1351 auf Port 2 steht danach in den Control Port Settings auch bei Port 1 die 1351.

    Aktiviert man mouse grab rührt sich nix. Ja, die Sensivity ist nicht vorhanden, wohl mit GTK3 verschütt gegangen. ;)

    Ist mir schon länger aufgefallen, wurde aber inzwischen gefixt.

    Bitte melde dich an, um diesen Link zu sehen.

  • 3. Maustreiber liest POT-Register und aktualisiert Mauszeiger,

    Dann sind das doch aber die Werte, die Port 1 sendet, oder nicht? Und das wird dann Käse sein, wenn die Maus an Port 2 hängt.

    Man wird ohnehin sinnvollerweise den Raster-IRQ anstelle des Tastatur-(CIA)-Interrupts verwenden, damit die Sprite-Register des Mauszeigers sauber "im Frame" geändert werden.

    Hmm. Alle Maustreiber, die ich bisher gesehen habe, benutzen den CIA-Interrupt für den Maustreiber.

    Bitte melde dich an, um diesen Link zu sehen. (Bitte melde dich an, um diesen Link zu sehen.)Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.
  • oder nicht?

    Oder nicht.

    Häng' meine oben beschriebene Abfolge in Gedanken mal zweimal untereinander. Wer (ver)stellt den Multiplexer auf Port 1? Die Tastaturabfrage in Punkt 6. Wer stellt den Multiplexer (wieder) auf Port 2? Der "Rest" des Maustreibers in Punkt 8. Wo werden die POT-Register gelesen? In Punkt 3, beim nächsten Interrupt. tWieviel Zeit vergeht zwischen Punkt 8 und Punkt 3? Circa 16 Millisekunden, die Zeit zwischen zwei Tastatur-IRQs. Ausreichend Zeit in denen sich die Combo Multiplexer-A/D-Wandler "einpendeln" kann und das Hauptprogramm ohne 4-ms-Busy-Wait unbehindert läuft.

    Beanworte dir die Frage jetzt selbst, welche Instanz als letztes vor der POT-Abfrage den Multiplexer eingestellt hat.

    Ganz am Anfang, die allererste Abfrage liest bei dieser Darstellung noch von Port 1. Nur die. Macht das was? Wenn dir das nicht gefällt, stell' den Multiplexer in der Init-Routine auf Port 2, warte hier eiin einziges mal 4 Millisekunden und gebe dann den IRQ frei. Brauchen tut's das aber nicht.

    Wenn dir das zur Erklärung nicht ausreicht, kann ich dir leider nicht weiterhelfen.

  • Habe den Tipp von Mac Bacon mit dem "Stack-Hack" umgesetzt und nun funktioniert mein Maustreiber auf Joystick-Port 2 ohne Warteschleife. Das Solitaire-Spiel wurde damit ganze 30 Prozent schneller. Vielen Dank an dieser Stelle für die vielen tollen Empfehlungen und Ideen. WebFritzi Den Weg über den Raster-IRQ habe ich fallen gelassen, weil das mit dem Lösungsansatz von Mac Bacon sehr viel eleganter und einfacher funktioniert.

    Hier der Link zur neuen Version des Treibers (als BASIC-Listing bzw. BASIC-PRG):

    Bitte melde dich an, um diesen Link zu sehen.

  • oder nicht?

    Oder nicht.

    Häng' meine oben beschriebene Abfolge in Gedanken mal zweimal untereinander. Wer (ver)stellt den Multiplexer auf Port 1? Die Tastaturabfrage in Punkt 6. Wer stellt den Multiplexer (wieder) auf Port 2? Der "Rest" des Maustreibers in Punkt 8. Wo werden die POT-Register gelesen? In Punkt 3, beim nächsten Interrupt. tWieviel Zeit vergeht zwischen Punkt 8 und Punkt 3? Circa 16 Millisekunden, die Zeit zwischen zwei Tastatur-IRQs. Ausreichend Zeit in denen sich die Combo Multiplexer-A/D-Wandler "einpendeln" kann und das Hauptprogramm ohne 4-ms-Busy-Wait unbehindert läuft.

    Wenn dir das zur Erklärung nicht ausreicht, kann ich dir leider nicht weiterhelfen.

    Doch, doch. Danke! Jetzt verstehe ich es. Naja, fast. Was mir noch unklar ist: Zur Beschreibung von $EA81 steht in der C64-Wiki:

    Holt Register A/X/Y aus dem Bitte melde dich an, um diesen Link zu sehen. zurück und beendet einen IRQ

    Was trage ich denn in den Dummy-Stackframe ein, damit mich $EA81 zum Rest des Maustreibers schickt, wo der Multiplexer eingestellt wird?

    Bitte melde dich an, um diesen Link zu sehen. (Bitte melde dich an, um diesen Link zu sehen.)Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.
  • Was trage ich denn in den Dummy-Stackframe ein, damit mich $EA81 zum Rest des Maustreibers schickt, wo der Multiplexer eingestellt wird?

    Das, was MacBacon im Solitaire-Thread geschrieben hat. Er hatte die gleiche Idee in dem anderen Thread und war auch schneller. Dafür steht hier meine etwas ausführliche Erklärung, wie es funktioniert.

    WebFritzi, ich würde dir schon anraten, dir mal genau anzuschauen was die CPU und der KERNAL beim Interrupt machen und wie die Stackbefehle und RTI arbeiten. Dann ergibt sich die Erklärung, ausgehend bereits von meinem Beitrag Bitte melde dich an, um diesen Link zu sehen., schon von selbst. Mit meinen Beiträgen Bitte melde dich an, um diesen Link zu sehen. und Bitte melde dich an, um diesen Link zu sehen. kam nichts substantiell neues dazu - die Blaupause in Beitrag Bitte melde dich an, um diesen Link zu sehen. reicht völlig aus, wenn man sich mit der Sache auskennt und nur noch nicht auf diese Idee gekommen war.

    wizball6502, saubere Umsetzung! 8o

  • WebFritzi, ich würde dir schon anraten, dir mal genau anzuschauen was die CPU und der KERNAL beim Interrupt machen und wie die Stackbefehle und RTI arbeiten. Dann ergibt sich die Erklärung, ausgehend bereits von meinem Beitrag Bitte melde dich an, um diesen Link zu sehen., schon von selbst.

    Das denke ich auch. Nur: wo finde ich eine solche Erklärung des Ablaufs? Ich würde gerne wissen, was da intern passiert.

    EDIT: Ich nehme an, du spielst auf das RTI am Ende der Routine in $ea31 an. Dort wird dann der Dummy aus dem Stack gezogen. Tastatur-IRQ und alles andere passiert vorher?

    Bitte melde dich an, um diesen Link zu sehen. (Bitte melde dich an, um diesen Link zu sehen.)Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

    Einmal editiert, zuletzt von WebFritzi (13. August 2021 um 14:15)

  • wo finde ich eine solche Erklärung des Ablaufs?

    Das Datenblatt der 65xx CPU und ein ROM-Listing sind deine Freunde.

    Jo, sicher. Schon der erste jsr in $ea31 verweist auf vier weitere jsr's im Kernal. In der ganzen Routine ist natürlich auch viel dabei, was ich gar nicht wissen will. Mich interessiert z.B. nicht, wie die Tastaturabfrage funktioniert, nur wo sie passiert. Was ich gerne hätte wäre ein grober Ablauf, wo was passiert.

    EDIT: Ok, stimmt nicht mit den JSRs. Das sind JMPs. Egal, mein Hauptpunkt bleibt, dass ich mir nicht stundenlang den Kernal-Code anschauen möchte.

    Bitte melde dich an, um diesen Link zu sehen. (Bitte melde dich an, um diesen Link zu sehen.)Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

    Einmal editiert, zuletzt von WebFritzi (13. August 2021 um 14:40)

  • Jo, sicher.

    Ganz genau!

    Schon der erste jsr in $ea31 verweist auf vier weitere jsr's im Kernal. In der ganzen Routine ist natürlich auch viel dabei, was ich gar nicht wissen will. Mich interessiert z.B. nicht, wie die Tastaturabfrage funktioniert, nur wo sie passiert.

    Bei einem gut kommentierten ROM-Listing ist das auch ganz klar ersichtlich und Du kannst die Sachen überspringen, die für die Anwendung erstmal nicht relevant sind.

    Was ich gerne hätte wäre ein grober Ablauf, wo was passiert.

    Ganz knallhart gesagt, da mußt Du dich jetzt selbst durchbeißen! Ich habe deine Frage wie man den Dummy-IRQ-Stackframe aufbaut im anderen Thread nochmal ausführlich beantwortet. Wie weit aufdröseln soll ich das denn jetzt noch? Du siehst doch, daß wizball6502 aufgrund der Blaupause von MacBacon ohne weiteres in der Lage war, den Maustreiber umzubauen und das, obwohl die Blaupause wesentlich knapper beschrieben war als hier in dem Thread. Also kriegen andere sowas hin. Es gibt also noch was für dich zu studieren und das nimmt dir niemand ab.

  • Du siehst doch, daß wizball6502 aufgrund der Blaupause von MacBacon ohne weiteres in der Lage war, den Maustreiber umzubauen und das, obwohl die Blaupause wesentlich knapper beschrieben war als hier in dem Thread.

    Das stimmt so nicht ganz. Du hast hier z.B. nicht beschrieben, was wie genau auf den Stack gepusht werden muss. Das wird erst in dem anderen Thread klar. Das hatte ich zuerst nur nicht gesehen, weil ich dachte, dass es dort um die Umsetzung per Raster-IRQ ging.

    Damit weiß ich nun natürlich, wie ich es implementiere. Am Umsetzen scheitert es sicher nicht. Es geht mir ums Verständnis. Ich weiß nun, dass $ea31 am Ende drei Bytes vom Stack zieht und die in Y,X und A schreibt und dann per RTI zur Adresse springt, die danach im Stack steht. Das ist dann der zweite Teil unseres Maustreibers. Ziemlich clever! Am Ende des Treibers wird dann $ea81 aufgerufen, was den ursprünglichen Stack-Frame zieht, und alles läuft normal weiter. So richtig?

    Um all das besser zu verstehen, wäre ein kommentiertes ROM-Listing in der Tat ideal. Ich habe jetzt ein solches gefunden: Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen. (Bitte melde dich an, um diesen Link zu sehen.)Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.