Der Herbst ist gekommen , der
Kohl hat geblüht , es ist fast mitten im Winter, und ich habe gerade damit fertig gemacht. Trotzdem ist die Zeit gekommen, in der Sie etwas Altes spielen möchten, zum Klang eines Schneesturms vor dem Fenster, zum Beispiel Sonic oder Jims Wurm. Am Ende des Artikels befindet sich ein Video mit vorläufigen Ergebnissen.

Wenn Sie SMD-Spiele auf dem Emulator gespielt haben, haben Sie wahrscheinlich bemerkt, dass das bequemste Gamepad für diese Spiele das native Gamepad von SMD ist. Für die meisten anderen Konsolen ist es beim Spielen auf dem Emulator durchaus möglich, mit demselben Xbox- oder Logitech-Gamepad auszukommen. Der Standard wurde gegen Ende der 90er Jahre entwickelt. Aber bis Ende der 90er Jahre haben sich alle Mühe gegeben, so gut er konnte.
Es ist nicht schwierig, ein Gamepad von SMD zu kaufen, und in der Regel können Sie es dort kaufen, wo die Klone der Konsolen selbst zu einem ziemlich erschwinglichen Preis von etwa 300 Rubel verkauft werden.
Nach wie vor organisierte ich die Verbindung zum Raspberry pi mit einem USB-Kabel aus dem stillgelegten Gehäuse und dem DB-9-Anschluss des Vaters. Und GPIO hat die Schlussfolgerungen im Programm gemalt. Das Gamepad funktioniert ab 3,3 Volt hervorragend.

Wie immer stellte sich die Frage nach der Auswahl eines Emulators, und die beste Option war der Emulator - Picodrive. Er ist für ARM optimiert, gut strukturiert und nach meinem Verständnis Teil der RetroPi-Assembly. Aber bei der Montage musste ich ein bisschen basteln. Der Quellcode befindet sich im Github-Dienst
unter dieser Adresse .
Zum Erstellen benötigen wir 3 Erfolgskomponenten aus dem Repository des Autors des Emulators:
- Picodrive-Emulator selbst;
- CPU-Emulator - cyclone68000;
- und FrontEnd - Libpicofe.
Jetzt muss alles richtig zusammengestellt werden. Packen Sie Picodrive aus oder entpacken Sie es nicht, je nachdem, wie Sie es heruntergeladen haben. Öffnen Sie nun das Verzeichnis mit
cyclone68000 , dessen Inhalt in das Verzeichnis kopiert werden muss:
/ /picodrive-master/cpu/cyclone
Sie müssen
sich auch mit dem Inhalt des
Libpicofe- Verzeichnisses
befassen. Der Inhalt wird in das Verzeichnis kopiert:
/ /picodrive-master/platform/libpicofe
Jetzt müssen Sie sich auf die Montage vorbereiten:
Konfiguration vornehmen
sudo ./configure
Nach Abschluss der Konfiguration wird eine Datei erstellt -
config.mak. Darin müssen Sie einige Zeilen suchen und ändern. Unten ist das fertige Ergebnis:
AS = arm-linux-as LDLIBS += -L/usr/lib/arm-linux-gnueabihf -lSDL -lasound -lpng -lm -lz -lwiringPi ARCH = arm PLATFORM = rpi1
Als nächstes müssen Sie die Datei -
config.h bearbeiten. Es befindet sich im Verzeichnis:
/ /picodrive-master/cpu/cyclone
Darin müssen Sie diejenigen in die Variablen einfügen:
#define HAVE_ARMv6 1 #define CYCLONE_FOR_GENESIS 1
Und jetzt der Software-TeilWie immer war es notwendig, einen Ort zu finden, an dem Informationen über die gedrückten Tasten verarbeitet werden,
den Code zu verstehen, zu
vergeben und zu ersetzen.
Ohne Spannung zu erregen, sage ich sofort, dass sich die gesuchten Dateien im Verzeichnis befinden:
/ /picodrive-master/pico/
Hier interessieren uns 3 Dateien -
pico.c ,
memory.c ,
memory.h . Wahrscheinlich können Sie mit einer kleineren Anzahl alles in eine packen, aber es schien mir einfacher.
Und so initialisiere ich in der Datei
pico.c die Bibliothek und konfiguriere zunächst die GPIO-Pins.
Ich werde sofort einen Teil des Datei-Headers angeben:
#include "pico_int.h" #include "sound/ym2612.h" #include <wiringPi.h> #define Data0 3 #define Data1 4 #define Data2 5 #define Data3 12 #define Data4 13 #define Data5 10 #define Select 6 struct Pico Pico; struct PicoMem PicoMem; PicoInterface PicoIn;
Wie Sie sehen können, wird die Überschrift der
WiringPi- Bibliothek
festgelegt und
Definitionen werden angekündigt, die etwas niedriger erscheinen. Nun, zum Beispiel jetzt in der Funktion
void PicoInit (void) :
void PicoInit(void) { ... ... PicoDraw2Init(); wiringPiSetup (); pinMode (Select, OUTPUT); pinMode (Data0, INPUT); pinMode (Data1, INPUT); pinMode (Data2, INPUT); pinMode (Data3, INPUT); pinMode (Data4, INPUT); pinMode (Data5, INPUT); digitalWrite (Select, HIGH); }
Dies ist eine Emulator-Speicherinitialisierungsfunktion (eine Art). Und hier habe ich alle Einstellungen der GPIO-Pins eingefügt.
Hier ist die Pinbelegung des DB-9-Steckers .
Hier muss ich sagen, dass das Gamepad 6 Informationskontakte (Data0 ... Data5), einen Controller (Selest) und Strom hat.
Als nächstes haben wir die gleichen Definitionen - definieren Sie, wir müssen es noch einmal wiederholen. Dies kann sowohl in
memory.h als auch in
memory.c erfolgen . Ich habe die erste Option gewählt. Es macht keinen Sinn, dies aufzulisten.
So kommen wir zum interessantesten - der Datei
memory.c . Es hat 2 Funktionen mit beredten Namen:
static u32 read_pad_3btn(int i, u32 out_bits) static u32 read_pad_6btn(int i, u32 out_bits)
Die Namen scheinen unauffällig darauf hinzudeuten, den Status von 3-Tasten- und 6-Tasten-Gamepads zu lesen.
Hier muss klargestellt werden, dass jedes 6-Tasten-Gamepad als 3-Tasten-Gamepad funktionieren kann. Und der Löwenteil der Spiele funktioniert genau mit diesem Modus des Gamepads. In diesem Modus ändert sich alle 16 Millisekunden der Status des Select-Ausgangs. Wenn Select = 0, werden die Werte der Schaltflächen gelesen - UP, DOWN, A, Start. Bei Auswahl = 1 wird der Status der Tasten gelesen - AUF, AB, LINKS, RECHTS, B, C. Nachfolgend finden Sie ein Beispiel für die Funktionsweise dieses Modus.

Ich werde sofort eine Liste dieser Funktion mit den Änderungen geben:
static u32 read_pad_3btn(int i, u32 out_bits) { u32 pad = ~PicoIn.padInt[i];
Hier ist
i die Nummer des Gamepads und der Ausdruck
if (out_bits & 0x40) // TH ist nur für den Status der Select-Ausgabe verantwortlich. Es ist anzumerken, dass im Emulator der Status der Schaltflächen in derselben Form wie in der Konsole angegeben wird. Taste gedrückt = 0.
Hier ist das Ergebnis der Arbeit:
Fortsetzung in der nächsten Serie,
Pip-Pip-Pip