Kleiner Maustreiber

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

  • Ziel dieses Threads ist es, das Thema Maustreiber aus Bitte melde dich an, um diesen Link zu sehen. outzusourcen, weil es dort schließlich um das Solitaire von wizball6502 gehen soll und nicht um meine Anfängerfragen zu Assembler. Ich habe nämlich die folgenden Fragen zu dem (funktionierenden) Code unten:

    1. Wie stellt der Code sicher, dass der Mouse-IRQ vor der Tastaturabfrage ausgeführt wird?
    2. Wozu speichert man den Standard-IRQ nochmal extra in IIRQ2? Steht da nicht immer $ea31 drin?
    3. Gibt es einen großen Unterschied zwischen der Verwendung von SEI..CLI und PHP SEI.. PLP (welches hier verwendet wird)?
    4. Sind die ersten drei Zeilen in INSTALL nicht überflüssig?
    5. Kann man meine langwierigen Fallabfragen vor MOVCHK irgendwie kürzer gestalten? Sie dienen dem Zweck, den Mauszeiger im C64-Rahmen zu halten.

    Der Code in Kleinbuchstaben ist von mir eingefügt. Der Rest ist der Treiber aus dem 1351-Manual.

    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.

    2 Mal editiert, zuletzt von WebFritzi (11. August 2021 um 15:35)

  • Ach Mensch, jetzt kann ich nicht mehr bearbeiten. Hab noch ne Frage. Der IRQ fragt Control Port 1 ab, ich hätte aber gerne die Maus in Port 2. Wie ändere ich den Code dementsprechend ab?

    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.
  • Den Port legt man in 56320 fest, $DC00 Bit 6 = 1 und Bit 7 = 0

    Bitte melde dich an, um diesen Link zu sehen.

    Ich hab für meine Spielereien aber bisher auch nur den mitgelieferten 1351 Treiber und die Maus in Port 1 verwendet.

  • Es gibt ja nur jeweils einen PotX- und PotY-Eingang am SID. Zwischen den beiden Ports wird daher mit einem Analogschalter 4066 umgeschaltet, der wieder über PA6/PA7 von CIA1 angesteuert wird. Diese Leitungen werden auch von der Bios-Tastaturabfrage umgeschaltet, was einer der Gründe ist, warum man einen Interrupt für die Maus braucht. Um vom Tastaturscan unbeeinflußte Ergebnisse zu bekommen, müssen die PotX/Y-Eingänge des richtigen Ports >1.6ms mit den PotX/Y-Eingängen des SID verbunden sein, bevor man die Werte ausliest.

    Kennst Du die 1351 Demodisk? Ansonsten siehe Anhang.

    Bitte melde dich an, um diesen Anhang zu sehen.

    Das "bessere" Demoprogramm von der C1541 Demodisk (M1351.64.*) schreibt tatsächlich entweder 0x40 (Port1) oder 0x80 (Port2) in CIA-Port-Register bei 0xDC00 und wartet dann 4ms vor dem Auslesen der POT-Werte.

    Das einfache Demoprogramm tut das aber nicht. Hier sind wohl (wie auch normalerweise ohne spezielle Programme) die beiden Pins PA6/PA7 die meiste Zeit high sein, weil die Kernal-Tastaturabfrage meines Wissens eine 0 (Low-Pegel) durch die Ausgänge PA0..PA7 schiebt. Nach dieser Logik wären alle vier Schalter des 4066 die meiste Zeit eingeschaltet und damit wären POTX/Y von PortA und PortB die meiste Zeit gleichzeitig quasi kurzgeschlossen. Das ist aber auch genau der Grund dafür, daß das eben das einfache Beispiel ist. Es geht halt auch irgendwie, aber es darf kein Paddle oder so am anderen Port angeschlossen sein und wenn man den Wert gerade einliest, während der Keyscan den Multiplexer deaktiviert, dann zuckt die Maus.

    -> Habe mir Deine Funktion nicht angeschaut, aber ich würde erwarten, daß irgendwo 0x40 nach 0xDC00 geschrieben wird und das müßtest Du in 0x80 ändern. Oder so.

  • Was auch cool ist: bei einer über Micromys angeschlossenen Maus kann man das Mausrad abfragen (Port 1: hoch=251, runter=247, 3. Button=253)

    Auch wenn man das für sich nutzen kann, wäre die Anwendergruppe wohl kaum präsent.

  • -> Habe mir Deine Funktion nicht angeschaut, aber ich würde erwarten, daß irgendwo 0x40 nach 0xDC00 geschrieben wird und das müßtest Du in 0x80 ändern. Oder so.

    Ganz ehrlich: den ganzen Hardware-Kram kapiere ich nicht. Der ein sagt, man muss warten, der andere (@Mac Baco) sagt nicht.

    In meiner Funktion wird gar nichts in $dc00 geschrieben. Aber ich habe jetzt $80 da reingeschrieben, und siehe da: es geht. Was ich wiederum nicht verstehe: auf der Lynx verlinken Paddle-Wiki-Seite steht

    Controlport 1 auswählenBit6=0 und Bit7=1
    Controlport 2 auswählenBit6=1 und Bit7=0

    Ist das nicht falsch rum?

    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.
  • IMHO muß das höherwertige Bit (7) gesetzt sein, 1<<7 = 0x80.

    Und wenn man nichts in 0xDC00 schreibt, dann steht da halt drin, was irgendjemand vorher reingeschrieben hat - im Zweifelsfall die Tastaturroutine des Kernals, wenn die nicht umgebogen wurde.

    Aber wie gesagt: eigentlich reicht es nicht, direkt vor dem Auslesen umzuschalten. Wenn die PotX/Y-Leitungen des SID vorher durch den Tastaturscan o.ä. mit dem anderen Port verbunden waren, braucht es eine gewissen Zeit, damit das Lade-/Entladespielchen mit den Kondensatoren abgeschlossen werden kann.

  • Aber wie gesagt: eigentlich reicht es nicht, direkt vor dem Auslesen umzuschalten. Wenn die PotX/Y-Leitungen des SID vorher durch den Tastaturscan o.ä. mit dem anderen Port verbunden waren, braucht es eine gewissen Zeit, damit das Lade-/Entladespielchen mit den Kondensatoren abgeschlossen werden kann.

    Und wie passt das dann mit der Aussage von Mac Bacon (Bitte melde dich an, um diesen Link zu sehen.) zusammen?

    Oder muss man nur warten, wenn man Port 2 nutzen möchte? Das Doofe ist echt, dass ich das hier nur auf einem Emulator ausprobieren kann.

    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.
  • Also ich kann nur sagen, wie PotX/Y-Eingänge nach meinem Verständnis funktionieren, weder wie genau sie in Emulatoren nachgebildet sind noch wie gut die Mausroutine in diesem Basicspiel funktioniert.

    Tatsache ist, daß PA6 von CIA1 die PotX/Y-Leitungen von PortA (1) mit dem SID verbindet und PA7 die PotX/Y-Leitungen von PortB (2). Wenn beide Bits gesetzt sind, dann sind sowohl PotX/Y von PortA als auch PotX/Y von PortB mit dem SID verbunden und damit untereinander kurzgeschlossen.

    Sicher ist auch, daß diese beiden Ausgänge des CIA1 Teil der Tastaturmatrix sind und deshalb von der Kernal-Tastaturroutine benutzt werden. Soweit ich weiß, programmiert die Kernal-Routine die Pins von PortA des CIA1 als Ausgänge und schiebt dann eine 0 (low-Pegel) von PA0 nach PA7 (0xFE wird geladen und dann per ROL rotiert und nach 0xDC00 geschrieben). Der Quelltext des Kernals läßt vermuten, daß am Ende des Keyboard-Routine immer ein Wert von 0x7F im Register 0xDC00 steht. Damit wäre PA6 high und PA7 low. Was PA6/7 angeht, wäre damit also PortA ausgewählt. Vermutlich bleibt dieser Wert stehen bis zum nächsten Interrupt. Habe das kurz in Vice ausprobiert und da ist es auch so:

    Code
    break ea31
    io dc00

    --> "Port A: 7f DDR: ff"

    Wenn man also am Anfang des umgebogenen IRQs PotX/PotY ausliest und zwischenzeitlich niemand 0xDC00 überschrieben hat, dann war ja längere Zeit PortA mit dem SID verbunden und das Auslesen der PotX/Y-Werte ist kein Problem. Vermutlich klappt deshalb die Mausroutine in dem Basicspiel auch ohne explizites Warten auf Port A. Wenn man nun allerdings am Anfang des umgebogenen IRQ-Handlers auf PortB umschaltet, indem man eine 0x80 nach 0xDC00 schreibt, dann muß man eine Zeit (>1.6ms) warten, bis der SID über seine Lade-/Entladefunktion die Widerstände an PotX/Y sicher ausmessen konnte. Keine Ahnung, wie exakt das Emulatoren nachbilden. Meine Vermutung wäre: gar nicht.

    Aus diesem Grund wartet der genannte "bessere" Maustreiber von der 1351 Demodisk knallhart 4ms im Treiber, nachdem er die CIA-Pins umgeschaltet hat. Ob das eine elegante Lösung ist, sei mal dahingestellt.

  • Tatsache ist, daß PA6 von CIA1 die PotX/Y-Leitungen von PortA (1) mit dem SID verbindet und PA7 die PotX/Y-Leitungen von PortB (2).

    Was sind PA6 und PA7? Auf der Wiki-Seite zum CIA finde ich dazu nichts.

    EDIT: Aha, Bits 6 und 7 von $dc00.

    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 (11. August 2021 um 20:25)

  • Jeder CIA hat zwei Ports (A und B) mit jeweils 8 Pins (0..7). PA6 und PA7 sind die Schaltplanbezeichnungen der Pins 6 und 7 von PortA.

    Alle diese 16 Pins sind jeweils als OpenDrain-Ausgang mit integriertem Pullup oder als Eingang benutzbar. Diese Auswahl geschieht über das jeweilige DDR-Register (DDRA/DDRB).

  • Aha, alles klar. Die Bits stehen auch gleichzeitig für die Pins des Chips.

    Alle diese 16 Pins sind jeweils als OpenDrain-Ausgang mit integriertem Pullup oder als Eingang benutzbar. Diese Auswahl geschieht über das jeweilige DDR-Register (DDRA/DDRB).

    Alle diese Bezeichnungen sagen mir rein gar nichts. Ich mag ja Programmieren, aber bei Hardware und Elektrotechnik geht bei mir gar nichts.

    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 wäre sehr dankbar, wenn jemand mal mein Programm (Anhang) mit 1351-Maus in Port 2 an echter Hardware testen könnte.

    Wenn man nun allerdings am Anfang des umgebogenen IRQ-Handlers auf PortB umschaltet, indem man eine 0x80 nach 0xDC00 schreibt, dann muß man eine Zeit (>1.6ms) warten, bis der SID über seine Lade-/Entladefunktion die Widerstände an PotX/Y sicher ausmessen konnte. Keine Ahnung, wie exakt das Emulatoren nachbilden. Meine Vermutung wäre: gar nicht.

    Also ich kann nur sagen, wie PotX/Y-Eingänge nach meinem Verständnis funktionieren, weder wie genau sie in Emulatoren nachgebildet sind noch wie gut die Mausroutine in diesem Basicspiel funktioniert.

    Demnach dürfte es nicht laufen.

  • Kannst du dir dann erklären, warum wizball6502 ohne die Warteschleife Probleme hatte?

    Weil er Port 2 haben wollte. Der Tastaturscanner verbindet am Ende ja den SID mit Port 1, und daher sind im nächsten Interrupt die POT-Werte von Port 1 bereits problemlos eingelesen worden.

    Ich verstehe halt auch nicht ganz, wieso hier sicher gestellt ist, dass der IRQ stets vor der Tastaturabfrage ausgeführt wird.

    Wie stellt der Code sicher, dass der Mouse-IRQ vor der Tastaturabfrage ausgeführt wird?

    Wenn bei eingeschaltetem Kernal ein Interrupt auftritt, wird der Interrupthandler des Kernals angesprungen. Dieser erledigt ein paar Kleinigkeiten und springt dann über $314 die "normale" Interruptroutine des Kernals an, wo unter anderem die Tastatur abgefragt und TI erhöht wird.

    Verbiegt man $314 auf eine eigene Routine und springt am Ende zur "normalen" Routine -> dann wird die eigene Routine natürlich immer direkt vor der "normalen" Routine ausgeführt.

    Wozu speichert man den Standard-IRQ nochmal extra in IIRQ2?

    Damit man weiß, wohin man am Ende der eigenen Routine springen muss.

    Steht da nicht immer $ea31 drin?

    Sobald der eigene Treiber installiert ist, nicht mehr. Der Beispielcode lässt sich daher mit anderen IRQ-Routinen kombinieren, solange diese ebenso "korrekt" programmiert wurden. Springt der eigene Code immer stur nach $ea31, sind alle vorher installierten Helferlein wieder weg.

    Liegt das evtl. irgendwie daran, dass in seinem Code bei der IRQ-Installation CLI verwendet wurde und oben nicht?

    Nein.

    Folgt nicht eigentlich immer auf ein SEI auch ein CLI? Offenbar nicht.

    Gibt es einen großen Unterschied zwischen der Verwendung von SEI..CLI und PHP SEI.. PLP (welches hier verwendet wird)?

    Ich könnte es erklären, aber ich glaube, der Lerneffekt ist deutlich größer, wenn Du es selbst herausfindest. :D

    Lies einfach mal nach, was SEI/CLI/PHP/PLP tun.

    Sind die ersten drei Zeilen in INSTALL nicht überflüssig?

    Ansichtssache. Sie verhindern eine Mehrfachinstallation, die zu einer Endlosschleife führen würde.

    Ganz ehrlich: den ganzen Hardware-Kram kapiere ich nicht. Der ein sagt, man muss warten, der andere (@Mac Baco) sagt nicht.

    Und wie passt das dann mit der Aussage von Mac Bacon zusammen?

    Der SID macht kontinuierlich Messungen. Jede davon braucht eine gewisse Zeit. Während dieser Zeit sollte man tunlichst nicht den mit dem SID verbundenen Port wechseln. Der Tastaturscanner wird alle 16 bis 20ms aufgerufen und wechselt mehrmals den mit dem SID verbundenen Port - aber am Ende verbindet er den SID mit Port 1. Bis zum nächsten Aufruf des Tastaturscanners ist der SID also 16 bis 20ms lang mit Port 1 verbunden. Direkt vor dem nächsten Aufruf des Tastaturscanners kann man also problemlos die POT-Werte von Port 1 abfragen, ohne extra warten zu müssen. Will man die Werte von Port 2 haben, muss man Port 2 auswählen und eine gewisse Zeit abwarten, und während dieser Wartezeit darf auf keinen Fall der Tastaturscanner aktiv werden.

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..

  • Mac Bacon Vielen Dank für die ausführliche Antwort auf meine Fragen.

    Wenn bei eingeschaltetem Kernal ein Interrupt auftritt, wird der Interrupthandler des Kernals angesprungen. Dieser erledigt ein paar Kleinigkeiten und springt dann über $314 die "normale" Interruptroutine des Kernals an, wo unter anderem die Tastatur abgefragt und TI erhöht wird.

    Verbiegt man $314 auf eine eigene Routine und springt am Ende zur "normalen" Routine -> dann wird die eigene Routine natürlich immer direkt vor der "normalen" Routine ausgeführt.

    Danke. Jetzt hab ich's kapiert. Erst wenn der Tastaturscanner durch den Kernal wieder "anspringt", wird Port 1 verbunden, was seine Zeit braucht. Hängen wir uns vorher ein, ist Port 1 bereits verbunden.

    Ansichtssache. Sie verhindern eine Mehrfachinstallation, die zu einer Endlosschleife führen würde.

    All diese Dinge kann man mMn auch weglassen, wenn man den Treiber nur für ein kleines BASIC-Programm braucht, wie es bei wizball6502 und bei mir der Fall ist. Und warum sollte das zu einer Endlosschleife führen? Ich trage ja nur noch einmal den Vektor in $314/15 ein.

    Will man die Werte von Port 2 haben, muss man Port 2 auswählen und eine gewisse Zeit abwarten, und während dieser Wartezeit darf auf keinen Fall der Tastaturscanner aktiv werden.

    Aha. Diese Abfrage hat also mit dem Tastaturscanner nichts zu tun, richtig? Der ist an Port 1 angeschlossen und soll da auch bleiben.

    Also muss ich die Maus an Port 1 auslesen, wenn ich das BASIC-Programm nicht ausbremsen will.

    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.

    2 Mal editiert, zuletzt von WebFritzi (11. August 2021 um 21:09)

  • Ich wäre sehr dankbar, wenn jemand mal mein Programm (Anhang) mit 1351-Maus in Port 2 an echter Hardware testen könnte.

    Habe das "Minesweep" von der TestDisk gerade auf meinem echten Brotkasten und einer MouSTer-Maus an Port2 ausprobiert.

    Zur Sicherheit habe ich vorher nochmal den "besseren" Maustreiber (Nummer 2/M1351.64.*) von der 1351-Demodisk ausprobiert und auf Port 2 konfiguriert: dieser Treiber funktioniert an Port 2 wunderbar.

    Demnach dürfte es nicht laufen.

    Dem ist leider so. Mit der Maus in Port 2 bewegt sich der Mauszeiger die ganze Zeit ruckelnd von oben nach unten, sobald man die Maus einmal berührt hat und das bleibt so, auch wenn man die Maus danach nicht anfaßt. Bewegungen der Maus haben keinen Einfluß. In Port 1 funktioniert die Maus dagegen.

    Das entspricht ehrlich gesagt meinen Erwartungen. Der Multiplexer ist erst zu kurz auf Port 2 umgeschaltet, also stammen die PotX/Y-Werte noch von Port 1. Ohne Maus in Port1 wird also nur irgendwelcher Mist gemessen. Wenn eine Maus eingesteckt ist, werden nach dem Ende des IRQs dutzendfach plausible PotY/Y-Werte an Port1 gemessen.

  • 0xdeadbeef Vielen lieben Dank für's Ausprobieren!

    In Port 1 funktioniert die Maus dagegen

    Mit dem Programm auf der Testdisk? Das wundert mich aber. Hier auf dem VICE ist dem nicht so. Das Programm läuft nur mit der Maus in Port 2.

    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.
  • Jupp. Finde ich jetzt eigentlich gar nicht überraschend. Wenn Du die PotXY-Werte direkt nach dem Umschalten des Multiplexers ausliest, kann das mit einem echten SID eigentlich überhaupt nicht funktionieren.

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

  • 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.

    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.
  • Der Credit-Screen zur Mausversion von Minesweep:

    Bilder

    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.

    2 Mal editiert, zuletzt von WebFritzi (12. August 2021 um 04:19)