Приставки > Джойстики и прочие манипуляторы
Восстановление геймпада (клона) от Sega Mega Drive 2
(1/1)
SEGA-man:
Имею стародельный геймпад, то есть шестикнопочный клон для Sega MD2 и как часто бывает с этими клонами с каплей - он перестал работать.
Я проерил провод и он звонится нормально, то есть провода целые и на удивление качественные (как телефонные).
У Hotpixel на гитхабе заметил интересный проект где он сделал переходник для мыши, с использованием arduino nano.
Я понимаю что arduino nano не совсем будет подходить, а вот если RPi-Zero ??
Может кто имел дело с таким?
Добавлено позже:
Вот еще нашел интересную статью, где человек восстанавливает геймпад при помощи atmega8
https://dzen.ru/a/Y4HEsPHGXi7GqIZL
Добавлено 9 ноября 2025 года:
Может кому-то довелось скачать код для атмеги8 из этой статьи: https://dzen.ru/a/Y4HEsPHGXi7GqIZL
Очень хочется глянуть.
В итоге написал Алексею (кластеру), который порекомендовал писать на C для Raspberry Pi Zero.
Скорее всего плата разбери попадет мне в руки только в след году, поэтому хотелось попросить мож у кого есть свои наработки на этот счет.
Думаю много людей захотят таким образом воостановить свои старые джойстики)
Фамиклон:
--- Цитата: SEGA-man от 09 Ноябрь 2025, 20:41:20 ---Думаю много людей захотят таким образом воостановить свои старые джойстики
--- Конец цитаты ---
А оно того стоит? С трехкнопочным проблем вроде нет, а если у кого вдруг поломался супер-пупер хороший джой о шести кнопках, проще выпилить каплю с рабочего китайского донора.
SEGA-man:
Думаю стоит, выпиливать каплю и резать текстолит зачем? Еще надо рабочую плату найти.
А так, купил на алишке разбери зеро за 150р, залил код и запаял вместо капли.
Тем более, что эта проблема, когда капля отмирает частая, и думаю многим пригодится решение на разбери зеро судя по посту в Дзене :)
Фамиклон:
--- Цитата: SEGA-man от 20 Ноябрь 2025, 21:21:54 ---Тем более, что эта проблема, когда капля отмирает частая, и думаю многим пригодится решение на разбери зеро судя по посту в Дзене :)
--- Конец цитаты ---
Про Дзен конечно улыбнуло. Не буду говорить о том, что по многим авторам статей там клиника плачет, но, тут у нас 30 подписчиков, 600 просмотров за три года. А точно падёж джоев прям массовая проблема? Совершенно ничего не имею против энтузиазма во всех проявлениях, но с практичной точки зрения человек всегда выберет наиболее простой и доступный вариант.
--- Цитата: SEGA-man от 20 Ноябрь 2025, 21:21:54 ---Еще надо рабочую плату найти.
--- Конец цитаты ---
На Али примерно от 350 рубасов, мне кажется, не так уж велика цена.
Nhisti:
Я бы понял так заморачиваться с оригинальным контроллером, они нынче стоят как чугунный мост, особенно шестикнопочники, тут же проще новый купить.
SEGA-man:
--- Цитата: Фамиклон от 21 Ноябрь 2025, 19:47:54 ---На Али примерно от 350 рубасов, мне кажется, не так уж велика цена.
--- Конец цитаты ---
Так я ж видел качество этих джойстиков и могу сравнить новодельный клон и стародельный. Стародельные клоны, как в моем случае, часто имели хорошие провода и крестовину.
Добавлено позже:
--- Цитата: SEGA-man от 23 Ноябрь 2025, 00:13:52 ---Так я ж видел качество этих джойстиков и могу сравнить новодельный клон и стародельный. Стародельные клоны, как в моем случае, часто имели хорошие провода и крестовину.
--- Конец цитаты ---
ну вот тебе и юзкейс, как говорится) Сможешь восстановить оригинальный джой. А я в данном случае хочу восстановить хороший клон
Фамиклон:
--- Цитата: SEGA-man от 23 Ноябрь 2025, 00:13:52 ---Так я ж видел качество этих джойстиков и могу сравнить новодельный клон и стародельный. Стародельные клоны, как в моем случае, часто имели хорошие провода и крестовину.
--- Конец цитаты ---
Дык я ж не предлагаю на замену, я предлагаю в качестве донора капли, секрет которой известен сеговцам и китайцам.
Sanyameloman:
--- Цитата ---А я в данном случае хочу восстановить хороший клон
--- Конец цитаты ---
По-моему, на том же "Водолее" продаются в том числе и хорошие платы для хороших клонов. Но, опять же - безумству храбрых поём мы песню :)
Только внимательно и проверять лучше на чём-нибудь, что не так жалко будет ежели что)
SEGA-man:
О чем вообще разговор? Ну покупайте эти платы и пилите текстолит сами. Зачем тут это флуд?
Sanyameloman:
--- Цитата: SEGA-man от 05 Декабрь 2025, 21:08:32 ---Ну покупайте эти платы и пилите текстолит сами. Зачем тут это флуд?
--- Конец цитаты ---
Может, из-за того, что название данной темы носит общий характер, а не сфокусировано только на восстановлении геймпада Атмегой, "Малиной" или чем-то ещё? :)
Люди предлагают варианты - изощрённые, конечно, но вполне логичные (для поставленной задачи) и экономичные.
Я же платы предлагал не для пилежа, а для полноценной замены неисправной (те платы такого же размера).
Лично мне интересно найти "вундермикруху", как на фото внизу. Плата из относительно свежего джоя для мега драйва, но в дизайне Сега Сатурн (даже вторую кнопку Mode сделали :biggrin:).
Поиск по обозначению на этом чипе ничего не дал - а жаль... А ведь такая микруха могла бы решить и вашу проблему (если, конечно, у вас не стоит задача восстановить геймпад именно путём программирования микроконтроллера/микрокомпьютера).
DaemoniX:
Такая микра и в геймпадах с переключателем на турбо была, но сейчас и там ничтожный шанс её найти, если брать новым. Только если на барахолках поиграть в лотерею.
Да и в обычных с надписью 16-bit могла попадаться.
Sanyameloman:
--- Цитата: DaemoniX от 06 Декабрь 2025, 10:58:20 ---Такая микра и в геймпадах с переключателем на турбо была
--- Конец цитаты ---
Что любопытно, применимо к шестикнопочному джою мега драйва нигде не нашёл полноценного решения на элементной базе - везде попадаются какие-то оговорки и "нюансы". Либо решения для трёхкнопочного джоя, либо для шестикнопочного с кучей логики, который при всём при этом может неадекватно работать с "трёхкнопочными" играми (схема внизу с доп. переключателем - сам не проверял). Хотя, казалось бы, для той же сеги сатурн, как выяснилось, проблема решается всего двумя 74HC153.
Nhisti:
--- Цитата: Sanyameloman от 06 Декабрь 2025, 22:23:31 ---может неадекватно работать с "трёхкнопочными" играми
--- Конец цитаты ---
Именно для этого и существует кнопка Mode
Sanyameloman:
--- Цитата: Nhisti от 07 Декабрь 2025, 16:09:17 ---Именно для этого и существует кнопка Mode
--- Конец цитаты ---
Вот по идее да - для запуска той же Golden Axe надо зажать MODE перед включением питания приставки, чтоб включить трёхкнопочный режим. Прям хоть проверь схемку-то :D
(И да: ясень пень, что китайщину так восстанавливать нафиг не надо - чисто "научный" интерес так сказать :))
RafGul:
--- Цитата: DaemoniX от 06 Декабрь 2025, 10:58:20 ---Такая микра и в геймпадах с переключателем на турбо была, но сейчас и там ничтожный шанс её найти, если брать новым. Только если на барахолках поиграть в лотерею.
Да и в обычных с надписью 16-bit могла попадаться.
--- Конец цитаты ---
У этой микросхемы пины не совпадают с выводами 315-5638, кнопки x, y, z, A, B, C замыкаются с землёй ч/з сопротивление 3,3кОм. Версия с турбо имеется ввиду.
RafGul:
--- Цитата: SEGA-man от 09 Ноябрь 2025, 20:41:20 ---Может кому-то довелось скачать код для атмеги8 из этой статьи: https://dzen.ru/a/Y4HEsPHGXi7GqIZL
--- Конец цитаты ---
Автор обновил ссылку!
На всякий случай:
SEGA-man:
Да, обновил но я чет не разобрался со сборкой, поэтому через ИИ сделал кода на Си.
Прикрепил архив с файлом.
У меня пока нет возможности его затестить, но может кто попробует и отпишет?
Он совместим с atmega88
SEGA-man:
Прочитав статьи по данной тематике, как например здесь и при помощи ИИ, мне удалось написать код на С который легко можно залить через Arduino Nano по SPI.
Для разработки и заливки решил использовать Platformio. Теперь хочется ревью от более опытного программиста, кто мог бы указать на баги.
--- Код: ---/*
* Sega Mega Drive / Genesis controller
* 3-button + proper 6-button extension
*
* MCU: ATmega8 / ATmega88
* Clock: 8 MHz (internal)
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <stdint.h>
/* ================= Sega DB9 mapping =================
*
* PD2 UP / X
* PD3 DOWN / Y
* PD4 LEFT / Z
* PD5 RIGHT / MODE
* PD6 A / B
* PD7 START / C
*
* PB7 TH / SELECT (input from console)
*
* All outputs are ACTIVE LOW
*/
/* ================= Button source =================
* Replace these macros with your real button inputs
* Note: Buttons are assumed to be active-low (pressed = LOW)
*/
#define BTN_UP() ((PINB & (1 << PB0)) == 0)
#define BTN_RIGHT() ((PINB & (1 << PB1)) == 0)
#define BTN_DOWN() ((PINB & (1 << PB2)) == 0)
#define BTN_LEFT() ((PINB & (1 << PB3)) == 0)
#define BTN_START() ((PINB & (1 << PB4)) == 0)
#define BTN_A() ((PINB & (1 << PB5)) == 0)
#define BTN_B() ((PINC & (1 << PC0)) == 0)
#define BTN_C() ((PINC & (1 << PC4)) == 0)
#define BTN_MODE() ((PINC & (1 << PC5)) == 0)
#define BTN_X() ((PINC & (1 << PC3)) == 0)
#define BTN_Y() ((PINC & (1 << PC2)) == 0)
#define BTN_Z() ((PINC & (1 << PC1)) == 0)
/* ================= Internal state ================= */
static volatile uint8_t phase = 0;
static volatile uint8_t isSix = 0;
static volatile uint8_t prevTH = 1;
static volatile uint8_t idleTicks = 0;
/* ================= Helpers ================= */
static inline void writeLo(uint8_t pin)
{
PORTD &= ~(1 << pin);
}
static inline void writeHi(uint8_t pin)
{
PORTD |= (1 << pin);
}
static inline uint8_t th_level(void)
{
return (PINB & (1 << PB7)) ? 1 : 0;
}
/* ================= Timer0 overflow (~1 ms) ================= */
#if defined(__AVR_ATmega8__)
ISR(TIMER0_OVF_vect)
#else
ISR(TIMER0_COMPA_vect)
#endif
{
/* Increment idleTicks atomically */
uint8_t ticks = idleTicks;
ticks++;
idleTicks = ticks;
if (ticks > 12) {
/* Disable interrupts to prevent race condition with main loop */
cli();
phase = 0;
isSix = 0; /* fallback to 3-button */
sei();
}
}
/* ================= TH polling ================= */
static inline void sega_poll_th(void)
{
uint8_t th = th_level();
if (th != prevTH) {
prevTH = th;
idleTicks = 0;
/* Disable interrupts to prevent race condition with ISR */
cli();
uint8_t p = phase;
if (++p >= 8) {
p = 0;
isSix = 1; /* successful 6-button detect */
}
phase = p;
sei();
}
}
/* ================= Sega output ================= */
static inline void sega_output(void)
{
uint8_t th = th_level();
/* release all lines */
writeHi(PD2); writeHi(PD3); writeHi(PD4);
writeHi(PD5); writeHi(PD6); writeHi(PD7);
/* ---------- 3 BUTTON MODE ---------- */
if (!isSix) {
if (th) {
BTN_B() ? writeLo(PD6) : writeHi(PD6);
BTN_C() ? writeLo(PD7) : writeHi(PD7);
} else {
BTN_UP() ? writeLo(PD2) : writeHi(PD2);
BTN_DOWN() ? writeLo(PD3) : writeHi(PD3);
BTN_LEFT() ? writeLo(PD4) : writeHi(PD4);
BTN_RIGHT() ? writeLo(PD5) : writeHi(PD5);
BTN_A() ? writeLo(PD6) : writeHi(PD6);
BTN_START() ? writeLo(PD7) : writeHi(PD7);
}
return;
}
/* ---------- 6 BUTTON MODE ---------- */
switch (phase) {
case 0:
case 1:
case 2:
if (!th) {
BTN_UP() ? writeLo(PD2) : writeHi(PD2);
BTN_DOWN() ? writeLo(PD3) : writeHi(PD3);
BTN_LEFT() ? writeLo(PD4) : writeHi(PD4);
BTN_RIGHT() ? writeLo(PD5) : writeHi(PD5);
}
break;
case 3:
if (th) {
BTN_B() ? writeLo(PD6) : writeHi(PD6);
BTN_C() ? writeLo(PD7) : writeHi(PD7);
} else {
BTN_A() ? writeLo(PD6) : writeHi(PD6);
BTN_START() ? writeLo(PD7) : writeHi(PD7);
}
break;
case 4:
/* 6-button ID phase */
writeLo(PD2); writeLo(PD3);
writeLo(PD4); writeLo(PD5);
break;
case 5:
if (!th) {
BTN_X() ? writeLo(PD2) : writeHi(PD2);
BTN_Y() ? writeLo(PD3) : writeHi(PD3);
BTN_Z() ? writeLo(PD4) : writeHi(PD4);
BTN_MODE() ? writeLo(PD5) : writeHi(PD5);
}
break;
case 6:
case 7:
/* These phases are not used in 6-button mode output */
/* Controller should be idle during these phases */
break;
}
}
/* ================= Main ================= */
int main(void)
{
/* Disable ADC (digital I/O only) */
ADCSRA &= ~(1 << ADEN);
/* PD2–PD7 outputs */
DDRD |= (1 << PD2) | (1 << PD3) | (1 << PD4) |
(1 << PD5) | (1 << PD6) | (1 << PD7);
/* TH input (PB7) - no pull-up needed, console drives it */
DDRB &= ~(1 << PB7);
/* Button inputs: PB0-PB5 */
DDRB &= ~((1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4) | (1 << PB5));
PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4) | (1 << PB5); /* Enable pull-ups */
/* Button inputs: PC0-PC5 */
DDRC &= ~((1 << PC0) | (1 << PC1) | (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5));
PORTC |= (1 << PC0) | (1 << PC1) | (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5); /* Enable pull-ups */
#if defined(__AVR_ATmega8__)
/* ---------- ATmega8 : Timer0 overflow ---------- */
/* F_CPU = 8 MHz
* Prescaler = 64
* Overflow period ≈ 2.048 ms
* idleTicks > 12 gives ~24.6 ms timeout
*/
TCCR0 = (1 << CS01) | (1 << CS00); /* clk/64 */
TCNT0 = 0; /* initialize counter */
TIMSK |= (1 << TOIE0); /* enable overflow interrupt */
#elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88PA__)
/* ---------- ATmega88 / ATmega88A / ATmega88PA / ATmega88PB ---------- */
/* F_CPU = 8 MHz
* Prescaler = 64
* OCR0A = 124 → 1 ms
*/
TCCR0A = (1 << WGM01); /* CTC */
TCCR0B = (1 << CS01) | (1 << CS00); /* clk/64 */
TCNT0 = 0; /* initialize counter */
OCR0A = 124;
TIMSK0 = (1 << OCIE0A);
#endif
sei();
while (1) {
sega_poll_th();
sega_output();
}
}
--- Конец кода ---
Навигация
Перейти к полной версии