4-Spieler Adapter (vier Joysticks)

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

C64 Studio
4 Joysticks am C64

Falls ihr eine tolle Idee, für einen Mehrspielertitel habt, der sogar drei oder vier Spieler gleichzeitig erlaubt, dann vermisst ihr beim C64 bestimmt die Möglichkeit weitere Joysticks anschließen zu können. Ihr müsst aber nicht verzweifeln 😉 , denn die gewünschten Ports können durch einen kleinen Adapter für den Userport zur Verfügung gestellt werden.

 

Der 4-Spieler Adapter
Einen von Individual Computers professionell gefertigten Adapter, könnt ihr für knapp 14,- Euro z. B. direkt bei Individual Computers oder Protovision erwerben.

Der 4-Spieler Adapter von Individual Computers
Der 4-Spieler Adapter von Individual Computers

 

Wer basteln möchte, kann sich einen solchen Adapter auch selbstbauen. Protovision war so freundlich und hat dazu eine Anleitung veröffentlicht.
Habt ihr wenig Erfahrung mit solchen Basteleien, dann rate ich euch unbedingt zum fertigen Adapter!
Der Userport ist direkt mit den CIA-Bausteinen des C64 verbunden und diese sind sehr empfindlich! Solltet ihr (im wahrsten Sinne des Wortes) ‚mistbauen‚, dann ist es ganz schnell um einen dieser Bausteine geschehen und ihr könnt euch nach neuen CIAs umschauen.

Wer es dennoch wagen möchte, braucht:

  • 1x Userportstecker ca. 2,50€
  • 2x 9-pol. D-Sub-Stecker (je nach Ausführung jeweils ab ca. 0,20€)
  • 1x 74LS257 inkl. Sockel ca. 1,00€
  • 1x kleine Streifen- oder Lochrasterplatine (ab ca. 0,50€)
  • den üblichen Kleinkram wie z. B. Litze und falls gewünscht ein Gehäuse

Die Bauanleitung findet ihr dann, wie oben bereits erwähnt, bei Protovision.

 

Funktionsweise
Bevor wir die Joysticks per Assembler auslesen, erstmal ein paar Worte zur Funktionsweise des Adapters.

74LS257
74LS257

Das Herzstück ist der 74LS257.

Dies ist ein elektronischer Umschalter, der insgesamt vier getrennte Schalter mit je zwei Eingängen (A & B) und einem Ausgang (Y) zur Verfügung stellt. Über Pin-1 (A/B) wird gesteuert, ob der Eingang A oder B zu Y durchgeschaltet wird.

A/B, so wie die vier Y-Ausgänge werden mit dem Userport verbunden. Da für die beiden Feuerknöpfe kein Schalter im 74LS257 mehr zur Verfügung steht, sind diese direkt mit dem Userport verbunden.

 

Die Beschaltung des Userports (Teil der Anleitung von Protovision) findet ihr auf dem folgenden Bild.

Userport-Belegung (Quelle: Protovision)

 

Wir können nun über den CIA auf den Userport zugreifen und somit über A/B (SJ – Selekt Joystick) zunächst den Joystick auswählen. Danach brauchen wir nur noch die Richtungen (Y-Ausgänge, UP, DN, LF, RT) und den Feuerknopf (F1, F2) zu prüfen, um unsere Eingaben zu erhalten.

 

Auslesen der ‘neuen‚ Joysticks
Habt ihr keinen 4-Spieler Adapter, dann könnt ihr euch trotzdem mit seiner Programmierung beschäftigen.

Dockingstation für TC64
Dockingstation für TC64

Die Docking-Station für das Turbo Chameleon 64 bietet unter anderem ebenfalls die Möglichkeit, vier Joysticks zu betreiben und ist zum eben gezeigten Adapter kompatibel.

 

 

 

Außerdem könnt ihr auch VICE verwenden!
Unter Einstellungen (1) => Userport Joystick Einstellungen... (2) könnt ihr VICE entsprechend konfigurieren. Es öffnet sich ein neues Fenster Extra Joystick Einstellungen  (3). Dort wird der CGA Userport Joystick Adapter (4) benötigt. Wählt dann noch aus, welcher Joystick in welchem Port ‘stecken‚ soll – Joystick in extra Port #1 (5) dies ist der dritte und  Joystick in extra Port #2 (6) ist der vierte Joystick. Dann kann es auch schon losgehen.

4-Spieler unter VICE
4-Spieler unter VICE

 

Auch die Routine zur Abfrage der zwei weiteren Joysticks findet ihr bei Protovision bzw. Individual Computers. Eigentlich braucht ihr mich also gar nicht.

Ich bette hier die Funktion aber mal in ein kleines Programm ein, mit dem ihr die vier Joysticks direkt testen könnt.

Dies ist unser Hauptprogramm. Wie ihr seht, nichts wirklich aufregendes. Zu Beginn definieren wir einige Konstanten und sorgen für unsere Bildschirmmaske jsr drawmask. Danach initialisieren wir den 4-Spieler Adapter jsr init4playerinterface. In unserer Hauptschleife ab .loop, prüfen und verarbeiten wir die Joystickeingaben jsr checkinput. Außerdem habe ich die drei verwendeten Funktionen ( drawmaskcheckinput und  init4playerinterface) bereits als leere Dummies angelegt, damit ihr das Programm jederzeit übersetzen und ausführen könnt.

Zu diesem Zeitpunkt bringt ein Start natürlich noch nichts, außer der Erkenntnis, dass es hoffentlich 😉 keine Fehler gibt.

 
Um die Maske anzuzeigen, verwende ich einfach die bekannte Kernalfunktion CHAROUT, die ihr an der Adresse $FFD2 findet. Wir lesen in drawmask gleich einfach die PETSCII-Codes für unsere Maske ein und geben sie über $FFD2 aus. Dabei verwenden wir auch einige der Steuercodes, die CHAROUT verarbeiten kann. Sollten euch diese nicht geläufig sein, dann werft vorher besser kurz einen Blick auf den PETSCII-Beitrag.

Ergänzt nun drawmask mit den folgenden Zeilen:

Wie ihr seht, setzen wir erstmal den Schleifenzähler auf 0, um mit dem ersten Zeichen zu beginnen. Dann holen wir uns hinter .loop das Zeichen. Falls es eine 0 ist, haben wir das Textende erreicht und springen zum Ausgang .exit. Anderenfalls rufen wir CHAROUT auf. Diese Kernalfunktion gibt das Zeichen aus dem Akku, an der aktuellen Cursorposition aus. Sobald wir von $FFD2 zurückkommen, erhöhen wir den Schleifenzähler. Dann verwenden wir ein bne .loop, damit die Schleife von Neuem beginnt. Dies hat den Vorteil, dass wir ein BYTE sparen. Ein jmp .loop würde drei BYTES, statt der zwei von bne benötigen. Außerdem verhindert es eine Endlosschleife, falls kein Textende gefunden wird. Der Nachteil ist freilich, dass nach spätestens 256 Zeichen Schluß ist. Dies reicht für unsere Maske aber. Sobald wir beim .exit angelangt sind, geht es zurück zum Aufrufer.

Die Daten für die Maske fügen wir nun am Programmende, hinter dem Label mask ein.

Den lesbaren Text habe ich hier direkt in „…„ angegeben. Zur besseren Unterscheidung, habe ich alle Steuerzeichen dezimal und alle grafischen Zeichen als Hexzahlen aufgeführt. So löscht ihr durch Ausgabe von 147 z. B. den Bildschirm oder setzt mit 156 die Zeichenfarbe auf lila. Um alle Zeichen zu ‚entschlüsseln‚, werft einfach einen Blick auf die Bilder / Tabellen unter ‚PETSCII‚.

Wenn ihr das Programm jetzt startet, dann solltet ihr einen ersten Blick auf die Maske werfen können. Allerdings ist diese noch komplett in lila gehalten.

4Spieler_002
Die Maske…

 

Kümmern wir uns nun um die Initialisierung. Ergänzt dazu  init4playerinterface um die folgenden Anweisungen.

Die Routine sorgt dafür, dass wir über BIT-7 den Joystick wählen können, daher wird diese ‚Leitung‚ auf Ausgabe gestellt. Die restlichen BITs liefern uns die Joystickeingaben zurück und stehen daher auf Eingang.

Wir nähern uns langsam dem Kern unseres Programmes. Wenden wir uns nun der Eingaberoutine checkinput zu, die in der Endlosschleife des Haupprogrammes laufend aufgerufen wird.

Die Funktion springt zunächst nach readjoysticks, um die aktuellen Eingaben der vier Sticks zu lesen. Dann verarbeiten wir in einer Schleife die Werte der vier Joysticks. Dazu verwenden wir die Zeropageadresse ZP_HELP1 (die wir oben bereits festgelegt haben) als Schleifenzähler und initialisieren diese mit 3. Bei .loop beginnt dann unser Schleife. Dort verarbeiten wir die Eingaben, des über ZP_HELP1 gewählten Joysticks, zunächst bei performinput. Holen uns danach die aktuelle Stick-Nr. ins Y-Register und damit dann einen Offset für die Farbausgabe aus der Tabelle offset in den Akku. Da wir diesen Offset gleich im Y-Register benötigen kopieren wir ihn mit tay dort hin. Damit rufen wir die Funktion drawcolors auf, um die Farben für den jeweiligen Joystick in der Maske zu setzen. Abschließend verringern wir ZP_HELP1 um eins und springen, solange der Wert nicht negativ ist, wieder nach .loop.

Die Mini-Tabelle offset könnt ihr am Programmende einfügen.

Diese Tabelle sorgt dafür, dass unsere Farbausgabe für jeden Joystick um sechs Zeichen nach rechts verschoben wird.

 

 Fügt jetzt noch die drei neuen Dummy-Funktionen vor mask hinzu…

 

Ihr könntet das Programm jetzt zwar wieder ausführen, es zeigt sich aber noch keine Änderung zum vorherigen Lauf.

Weiter geht es mit dem eigentlichen Herzstück, der Ausleseroutine readjoysticks. Da diese gleich den Status der vier Sticks liest, brauchen wir noch einen Platz, an dem wir die ermittelten Werte erstmal ablegen können. Fügt dazu am Programmende die Tabelle joyvalues hinzu.

 

Nun kommen wir zur eigentlichen Funktion:

Die ersten Zeilen sollten euch eigentlich bekannt sein. Falls nicht, werft mal einen Blick in die Tastaturmatrix, dort findet ihr auch einige Infos zu den Joysticks. Habt ihr größeren Informationsbedarf, dann beschäftigt euch am besten erstmal mit ‚L.O.V.E.‚. Hier lesen wir die beiden standard Joysticks in Port-1 & 2 des C64 aus. Wir bereinigen die Daten etwas, da wir nur die unteren fünf BITs benötigen und merken uns die Werte in der eben angelegten Tabelle joyvalues.

Lesen wir nun die Werte für den dritten Joystick aus, der ja am 4-Spieler Adapter hängt.

Wir setzen im CIA-2 für Port-B $DD01 das BIT-7 auf 1, um die entsprechende Joystickbuchse am Adapter zu wählen. Danach lesen wir diesen Port einfach und erhalten unsere Joystickwerte. Auch hier benötigen wir nur die unteren fünf BITs und speichern das Ergebnis wieder unter joyvalues.

Der vierte und letzte Joystick ist etwas ‚tricky‚. Wenn ihr oben auf die Userportbelegung schaut, dann erkennt ihr, dass der letzte Feuerknopf nicht direkt neben den Richtungen liegt. Das kommt, wie bereits erklärt, daher, dass der 74LS257 nur vier elektronische Schalter bietet und die Feuerknöpfe deshalb direkt mit dem Userport verbunden sind. Das Problem ist aber nicht allzu groß, wir müssen das eine BIT nur um eine Stelle verschieben.

Diesmal wird das BIT-7 im CIA-2 auf 0 gesetzt, um den vierten Joystick zu wählen. Danach lesen wir, wie eben, $DD01 einfach wieder aus. Jetzt haben wir im Akku zwar die Werte des 4. Joysticks, da das BIT für den Feurknopf aber verschoben ist, sollten wir dies noch korrigieren, damit alle vier Werte identisch aufgebaut sind. Wir merken uns den Akku erstmal auf dem Stack, blenden die oberen vier BITs aus und speichern das Ergebnis schonmal bei joyvalues. Dort stehen jetzt nur die Richtungsinformationen! Um das BIT für den Feuerknopf an die gewünschte Position zu bekommen, holen wir den ursprünglichen Wert wieder vom Stack. Dann blenden wir alles, bis auf das BIT für die Feuertaste aus und verschieben den Akkuinhalt um ein BIT nach rechts. Jetzt müssen wir nur noch den Akku mit dem unter joyvalues gemerkten Wert ODER-Verknüpfen und das Ergebnis abschließend wieder dort ablegen.

Somit finden wir die Richtungs- & Feuerinformationen von allen vier Joysticks in einem einheitlichen Format unter joyvalues wieder.

 

Auch jetzt lohnt es sich nur, das Programm zu erstellen, wenn ihr prüfen möchtet, ob es sich fehlerfrei übersetzen läßt.

Zur Entspannung kümmern wir uns erstmal um drawcolors. Diese Routine setzt die Farben für den jeweiligen Joystick. Dazu wird wieder eine kleine Tabelle, mit dem passenden Namen colors, benötigt. Fügt diese einfach am Ende ein.

Als Ausgangsfarbe verwende ich die oben festgelegte Konstante COLOR_UNUSED. Da die Farben nur von 0 bis 15 gehen, wird das Zeilenende durch 16 definiert. Mit 255 legen wir das Ende der gesamten Tabelle fest. Wir werden diese Tabelle gleich über performinput füllen. Dort ermitteln wir, für den jeweils aktuellen Joystick, immer die benötigten Zeichenfarben und speichern sie hier.

Schreiben wir jetzt erstmal die Funktion, die diese Tabelle verarbeitet.

Der Routine wird im Y-Register der aktuelle Offset übergeben. Das X-Register nutzen wir als Schleifenzähler und initialisieren es mit 0. Hinter .loop beginnen wir damit, aus der Tabelle colors, das über X angegebene BYTE zulesen. Sollte es negativ sein, dann sind wir am Ende der Tabelle angelangt und verlassen die Funktion über einen Sprung nach .exit. Anderenfalls prüfen wir noch, ob es sich um einen Zeilenumbruch handelt. Sollte im Akku keine 16 stehen, dann springt das Programm nach .skip, sonst läuft es weiter und sorgt für einen Zeilenvorschub. Für den Umbruch addieren wir einfach 40 (Anzahl der Zeichen für eine Zeile auf dem Bildschirm) minus 4 (also 36) auf den Offset im Y-Register. Wir müssen 4 weniger addieren, da ein Umbruch immer am Ende einer Zeile aus colors erfolgt und wir vier BYTEs je Zeile benötigen. Nach dem Umbruch geht es bei .skip1 weiter. Stand keine 16 im Akku, dann wird hinter .skip die im Akku befindliche Farbe ins Farb-RAM geschrieben. Das Y-Register bestimmt dabei unseren Offset vom linken Rand. Die Adresse $D800+41 zeigt direkt das erste Zeichen von „JOY1″. Anschließend erhöhen wir den Offset im Y-Register und auch unseren Schleifenzähler im X-Register jeweils um eins. Das bne spart wieder ein BYTE und verhindert eine Endlosschleife.

Jetzt solltet ihr das Programm mal wieder starten…

Alle vier Joysticks werden als inaktiv angezeigt.
Alle vier Joysticks werden als inaktiv angezeigt.

Die Ausgabe hat sich etwas geändert. Nun werden alle Joysticks als inaktiv (dunkelgrau) angezeigt. Ihr könnt die Farbe ganz einfach über die Konstante COLOR_UNUSED ändern.

Haltet durch, es fehlt nur noch die Funktion performinput.

Die Routine holt sich die aktuelle Joystick-Nr. von ZP_HELP1 ins Y-Register und lädt damit die zum Joystick gehörenden Eingaben von joyvalues in den Akku. Danach kontrollieren wir, ob überhaupt eine Eingabe vorliegt, falls nicht springen wir direkt nach .oben, wo das Grau aus COLOR_UNUSED für den inaktivien Joystick ins X-Register geladen wird. Beachtet, dass die Joystickwerte low aktiv sind! Eine 1 bedeutet also keine Eingabe und eine 0, dass die Richtung bzw. der Feuerknopf gedrückt wurde! Sollte eine Eingabe vorliegen, dann laden wir COLOR_JOY_ACTIVE (gelb) ins X-Register und müssen die Zeile mit COLOR_UNUSED überspringen, daher jmp .oben1. Hinter .oben1 setzen wir in unserer Farbtabelle colors jetzt einfach die Farbe für die vier Zeichen der JOYx-Überschrift.

Ich möchte hier mal einen kleinen ‚Trick‚ zeigen. Mit dem ihr zwei BYTEs sparen könnt, allerdings kostet er euch einen Taktzyklus und ändert das Statusregister (SR)!
Ihr werdet evtl. häufiger in die Verlegenheit kommen, dass ihr wie eben, entweder Anweisung-A oder Anweisung-B ausführen möchtet. Das führt häufig zu dem gerade gesehenen Konstrukt:

Es wäre doch schön, wenn wir uns den Sprung jmp .oben1 und das dazugehörige Label sparen könnten. OK, auf das Label ließe sich leicht durch jmp *+5 verzichten. Es bleibt aber noch der Sprung. Hier können wir den absoluten BIT-Befehl (OpCode $2C) zweckentfremden!
Ersetzt ihr jmp .oben1 durch !BYTE $2C, dann wird ldx #COLOR_UNUSED als Adresse der BIT-Anweisung interpretiert und das Programm läuft automatisch beim jetzt überflüssigen Label .oben1 weiter. Damit man die Bedeutung der Anweisung im Quellcode leichter erkennt, können wir beim C64 Studio ein Macro anlegen.
Fügt am Anfang des Quellcodes, hinter den Konstanten, die folgenden Zeilen ein:

Jetzt könnt ihr im Source mit +FAKE_BIT dieses Macro aufrufen, sobald ihr einen falschen BIT-Befehl benötigt. Dieses Vorgehen klappt natürlich nur, wenn ihr exakt zwei BYTEs überspringen müsst. Anderenfalls benötigt ihr doch wieder einen Sprung! Beachtet außerdem, dass sich auch das Statusregister (SR) durch diesen Befehl ändert.

Unser Block von eben sieht dann so aus…

Lasst uns dieses Vorgehen für die restliche Funktion beibehalten.

Eben haben wir nur geprüft, ob es überhaupt Eingaben gibt. Jetzt kontrollieren wir die einzelnen Richtungen und den Feuerknopf. Im Akku befindet sich immer noch die Eingabe des aktuellen Joysticks. Wir verschieben diese jetzt bitweise nach rechts und schauen, ob eine Eingabe vorliegt. Los geht es mit OBEN…

Wie angekündigt, verschieben wir den Akkuinhalt um ein BIT nach rechts. Dabei landet das rausgefallene BIT im Carry-Flag. Sollte es gesetzt sein, dann fand keine Eingabe statt (low aktiv) und es geht bei .unten weiter. Anderenfalls holen wir uns die Farbe COLOR_JOYDIR (grün) für die Richtungen ins X-Register. Dann folgt unser Macro +FAKE_BIT, mit dem wir den ersten 2-BYTE-Befehl hinter .unten einfach auslassen. Wurde die Richtung OBEN nicht betätig, dann landen wir direkt bei .unten und holen wieder COLOR_UNUSED ins X-Register! Anschließend schreiben wir die ermittelte Farbe einfach in unsere Tabelle colors. Das Dreieck nach oben besteht nur aus zwei Zeichen, für das wir hier die Farbwerte setzen.

Da die restliche Funktion den eben gezeigten Block eigentlich nur für die anderen Richtungen und den Feuerknopf wiederholt, hier einfach die komplette Routine performinput. Die Kommentare sollten zur Erklärung reichen.

 

Jetzt ist unser kleines Testprogramm fertig und eure Joystickeingaben werden entsprechend angezeigt.

Die vier Joysticks testen
Die vier Joysticks testen

 


Damit solltet ihr für eure kommenden Multiplayerspiele gewappnet sein. Der hier beschriebene 4-Spiele Adapter wurde übrigens ursprünglich für „Bomb Mania„ entwickelt. Mittlerweile unterstützen ihn aber eine Reihe weiterer Spiele, wie z. B. IK+ Gold, M.U.L.E. oder Marble Madness. Damit stellt er wohl so eine Art Standard dar.


Schrott!!Naja...Geht so...Ganz gut...SUPER! (2 Bewertungen | Ø 5,00 von 5 | 100,00%)

Loading...


 

<<< zurück |

 

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Protected by WP Anti Spam