Neues Solitaire (Kartenspiel) für den Commodore 64 in BASIC V2 - Gratis Abtipp-Listing zum Herunterladen (PDF)

Es gibt 140 Antworten in diesem Thema, welches 24.525 mal aufgerufen wurde. Der letzte Beitrag (22. Dezember 2021 um 16:39) ist von WebFritzi.

  • Auf meinem originalen C64 (6581) hatte das ohne Pause nicht funktioniert.

    Was auch immer das Problem gewesen ist: Warteschleifen im Interrupt sind nicht die Lösung (tm).

    Offenbar ist es immer noch ein Problem auf echter Hardware. Hier mal ein Auszug aus dem deutschen 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.
  • Auf meinem originalen C64 (6581) hatte das ohne Pause nicht funktioniert.

    Was auch immer das Problem gewesen ist: Warteschleifen im Interrupt sind nicht die Lösung (tm).

    Ja, das wäre vielleicht ein "Wir bauen den perfekten 1351 Maustreiber"-Thread wert 😋. Ich habe den Solitaire-Maustreiber damals auf Basis eines bereits existierenden Treibers aufgebaut und der war, glaube ich, ein 1351 Treiber aus einer 64er. Optimiert habe ich dabei aber nur die Länge des Treibers (sollte max. 256 Bytes sein). Die Warteschleife hatte ich gar nicht hinterfragt bzw. als die einzig funktionierende Lösung (reale Hardware) betrachtet und so übernommen. Cool, dass da nun ein Optimierungspotential entdeckt wurde. Vielen Dank dafür.

    Ich bin zur Zeit auf Urlaub (kein Compi erlaubt) und kann erst Freitag mal schauen, ob mir was besseres einfällt.

  • Im Manual wird versprochen, dass der folgende Code die beschriebenen Probleme löst. Ich werde heute Abend mal damit rumspielen. Aber ich muss gleich sagen, dass ich den ganzen Hardware-Kram nicht kapiere.

    wizball6502 Wer ist "Eye of the Beholder"?

    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.
  • Es gibt da sowohl die TOD (Time of Day), als auch Timer, um einen Interrupt auszulösen.

    Ok, aber der Timer taktet ja wohl im CIA, oder nicht? Dann wäre meine Originalaussage ja richtig. Der Turbo-Mode sollte ja nur den 6510 betreffen und nicht die CIAs.

    Da hast du recht und ich hatte einen Denkfehler, was das Verhalten bei einer Beschleunigung betrifft.

    Mit dem erwähnten Timer in der CIA kann beeinflusst werden, wie oft ein Interrupt ausgelöst wird. So wird der Interrupt vom Kernal gesteuert, der Wert für die Häufigkeit ist dabei konstant. In der Interruptroutine wird dann TI bzw. TI$ gesetzt, indem die entsprechenden Speicherzellen hochgezählt werden. Da das also rein per Software ohne "Jitterkorrektur" (das Verhältnis von Interrupthäufigkeit/Sekunde geht nicht auf) im Interrupt geschieht, der seinerseits z.B. auch vom Kernal abgeschaltet werden kann, ist TI$ allerdings nicht sehr genau.

  • Naja, das sind ca. 3200 Zyklen, also 3 Millisekunden. Also quasi nix. Ich verstehe nicht, warum das das BASIC dermaßen ausbremst.

    Passiert das bei jedem Interrupt?

    Der Kernal-Interrupt wird durch CIA1 erzeugt und kommt mit 60Hz, d.h. alle 16.667 Millisekunden. Wenn man davon jedes Mal 3ms vertrödelt, bleiben für das Hauptprogramm nur noch 13.667 von 16.667ms übrig, das sind 82%.

    18 Prozent Rechenzeitverlust sind fast ein Fünftel, nicht "quasi nix". :D

    Da man eigene Programme meist mit dem BIldaufbau synchronisieren will und deshalb den Interrupt vom VIC machen lässt, ändern sich die Werte dann natürlich zu "50Hz", "alle 20ms", "17 von 20", "85%" -> 15% Verlust. Man muss dann natürlich die ggfs. nötige TI-Korrektur im Hinterkopf behalten.

    Hier mal ein Auszug aus dem deutschen 1351-Manual:

    Da steht doch schon die Lösung: Am Anfang der IRQ-Routine haben die Leitungen einen stabilen Zustand, schließlich liegt die letzte Tastaturabfrage schon 16.667ms (bzw. 20ms bei einem 50Hz-IRQ) zurück.

    Ich habe den Solitaire-Maustreiber damals auf Basis eines bereits existierenden Treibers aufgebaut und der war, glaube ich, ein 1351 Treiber aus einer 64er.

    Da hätte ich Bitte melde dich an, um diesen Link zu sehen. anzubieten.

    EDIT: Vor einiger Zeit ist mir aufgefallen, dass mein Treiber gar keine Möglichkeit bietet, die 16-Bit-X-Position sicher auszulesen, also ohne dass sich der Wert zwischen dem Lesen der beiden Bytes ändern kann. Sollte das jemand brauchen, steck ich da vielleicht noch mal Arbeit rein... ;)

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

  • Wer ist "Eye of the Beholder"?

    Das ist ein Bitte melde dich an, um diesen Link zu sehen., das gerade mit Mausunterstützung für den C64 umgesetzt wird: Bitte melde dich an, um diesen Link zu sehen.

  • Bitte melde dich an, um diesen Link zu sehen.

    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 Mein "hausgemachtes" Problem ist halt, dass ich ein Abtippspiel auf max. 3 A4 Seiten anbieten möchte (inkl. Datazeilen) und habe dabei auf einen möglichst reduzierten, aber funktionsfähigen 1351 Treiber gesetzt. Wäre das deiner Meinung/Erfahrung nach machbar, einen besseren 1351 Maustreiber mit max. 256 Bytes hinzukriegen? Als Gegenargument für diesen Sparansatz könnte man natürlich geltend machen, dass ein/e Enduser/in einfach die Maus, die er/sie vorrätig hat einstöpseln und loslegen will. Das spräche dann eher für ein zusätzliches eigenes Abtipplisting bzw. Downloadlink für den DuoDriver, den du verlinkt hast.

  • So, ich habe jetzt mal den Code aus dem Manual genommen, und es passiert - nichts. Der Sprite hängt die ganze Zeit bei x=24 rum und bewegt sich nicht. Mein vollständiges Programm sieht folgendermaßen aus (C64Studio):

    Komischer Weise lässt sich der Monitor von VICE nicht mehr starten, sobald das Programm läuft. Bin mal wieder verwirrt.

    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.
  • es passiert - nichts. Der Sprite hängt die ganze Zeit bei x=24 rum und bewegt sich nicht. Mein vollständiges Programm sieht folgendermaßen aus

    assembliert, in VICE gestartet, für Port 1 eine 1351 konfiguriert, "enable mouse grab" -> alles klappt wie es soll.

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

  • assembliert, in VICE gestartet, für Port 1 eine 1351 konfiguriert, "enable mouse grab" -> alles klappt wie es soll.

    Oh Mann! Ich hatte die ganze Zeit die Maus in Port 2. Danke dir vielmals!!!

    Und wo wird da jetzt das mit dem Timing sichergestellt?

    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äre das deiner Meinung/Erfahrung nach machbar, einen besseren 1351 Maustreiber mit max. 256 Bytes hinzukriegen?

    Der 1351-Teil von "Mousetest" ist 200 Byte groß. Und "DuoDriver" hab ich nicht verlinkt, damit Du das Programm unverändert benutzt, sondern damit Du Dir den Source ansiehst. ;)

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

  • Und wo wird da jetzt das mit dem Timing sichergestellt?

    Da der Treibercode im Interrupt hängt und immer direkt vor der Tastaturabfrage ausgeführt wird, muss man da nichts mehr sicherstellen - die Leitungen hatten ja seit dem letzten Interrupt genug Zeit (16 bis 20ms), um einen stabilen Zustand einzunehmen.

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

  • So. Ich habe den IRQ von oben mal etwas modifiziert, so dass der Cursor auch innerhalb der Rahmengrenzen bleibt. Wir sind damit immer noch knapp unter 256 Byte ($0900 - $09F1), aber da lässt sich bestimmt noch was optimieren. Ich bin erstmal froh, dass ich das hinbekommen habe.

    Mac Bacon Kannst du dir dann erklären, warum wizball6502 ohne die Warteschleife Probleme hatte? Liegt das evtl. irgendwie daran, dass in seinem Code bei der IRQ-Installation CLI verwendet wurde und oben nicht? Folgt nicht eigentlich immer auf ein SEI auch ein CLI? Offenbar nicht. Ich verstehe halt auch nicht ganz, wieso hier sicher gestellt ist, dass der IRQ stets vor der Tastaturabfrage ausgeführt wird. Und ganz wichtig: wie stelle ich auf Port 2 um? :wink:

    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.

    4 Mal editiert, zuletzt von WebFritzi (11. August 2021 um 05:03)

  • Eigentlich wäre es ja praktisch, wenn die Maus grundsätzlich in Port 1 wäre und ein Joystick jeweils in Port 2. Ich habe die Maus dann aber auf Port 2 angepasst, weil bei Texteingaben via Input (Eingabe des gewünschten Seeds) die Maus in Port 1 bei Mausklick unerwünschte Textzeichen generiert hat. Das war jedenfalls der Grund auf Port 2 zu gehen. Hätte man vielleicht auch anders lösen können.

  • Mit meinen Anfängerfragen zur Maustreiberprogrammierung mit Assembler geht es hier weiter: Bitte melde dich an, um diesen Link zu sehen.

    Mac Bacon Du scheinst dich ja gut mit Maustreibern auszukennen. Dann interessiert dich vielleicht auch der folgende Artikel vom C64OS-Macher: 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.

    Einmal editiert, zuletzt von WebFritzi (11. August 2021 um 15:54)

  • Eigentlich wäre es ja praktisch, wenn die Maus grundsätzlich in Port 1 wäre und ein Joystick jeweils in Port 2. Ich habe die Maus dann aber auf Port 2 angepasst, weil bei Texteingaben via Input (Eingabe des gewünschten Seeds) die Maus in Port 1 bei Mausklick unerwünschte Textzeichen generiert hat. Das war jedenfalls der Grund auf Port 2 zu gehen. Hätte man vielleicht auch anders lösen können.

    Ich bevorzuge die Maus in Port 1, einfach weil die meisten Joystick-Spiele den Joystick in Port 2 erwarten. Dass die Maus an Port 1 ohne Wartezeit auslesbar ist, kommt dann noch dazu...

    Das Problem mit falsch erkannten Tastendrücken hat ja nichts mit der Maus zu tun, das passiert bei Joysticks ebenso. Aber während der Benutzer Maustaste/Joystickbutton gedrückt hält, wird er ja eh nicht tippen, also muss man nur dafür sorgen, dass die falschen Eingaben ignoriert werden:

    Lösungsmöglichkeit 1: Wenn der Treiber eine Maus/Joystickaktion erkennt, springt man am Ende nicht zur Standard-IRQ-Routine des Kernals, sondern etwas weiter, d.h. man überspringt den Tastaturscanner (bitte den Einsprungpunkt selbst bei AAY64 heraussuchen).

    Lösungsmöglichkeit 2: Wenn das Spiel eine Maus/Joystickaktion erkennt (wie auch immer das beim jeweiligen Treiber gelöst sein mag), so wird per POKE198,0 der Tastaturpuffer gelöscht.

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

  • Dass die Maus an Port 1 ohne Wartezeit auslesbar ist, kommt dann noch dazu...

    Aha. Das heißt, dass eine Warteschleife für eine Maus an Port 2 schon notwendig ist?

    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.
  • Nur mal so am Rande: daß die Maus an PortA "ohne Warteschleife" möglich ist, liegt nur daran, daß die Tastaturabfrage des Kernals am Ende immer eine 0x7F in 0xDC00 zurückläßt, was PortA mit dem SID verbindet. Also bleiben PotX/Y des SID bis zum nächsten IRQ immer mit PortA verbunden und man kann die Werte am Anfang des IRQ-Handlers sofort auslesen.
    Wenn man ein richtiges Spiel mit eigener Tastaturabfrage programmiert, gibt es dieses Problem nicht mehr, weil man 0xDC00 am Ende des IRQ-Handlers mit jedem beliebigen Wert beschreiben kann. Lassen wir mal dahingestellt, ob es nicht auch eine elegantere Lösung mit dem Kernal-IRQ-Handler gäbe, aber das ganze Thema ist so oder so nur ein Problem für Spiele, die den Kernal-IRQ-Handler benutzen wollen. Also im wesentlichen solche in Basic.