Автор Тема: Восстановление геймпада (клона) от Sega Mega Drive 2  (Прочитано 2035 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн SEGA-man

  • Пользователь
  • Сообщений: 61
  • Пол: Мужской
    • Просмотр профиля
Имею стародельный геймпад, то есть шестикнопочный клон для 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.
Скорее всего плата разбери попадет мне в руки только в след году, поэтому хотелось попросить мож у кого есть свои наработки на этот счет.
Думаю много людей захотят таким образом воостановить свои старые джойстики)
« Последнее редактирование: 29 Январь 2026, 18:11:54 от ghostdog3 »

Оффлайн Фамиклон

  • Пользователь
  • Сообщений: 1188
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #1 : 11 Ноябрь 2025, 07:43:45 »
Думаю много людей захотят таким образом воостановить свои старые джойстики
А оно того стоит? С трехкнопочным проблем вроде нет, а если у кого вдруг поломался супер-пупер хороший джой о шести кнопках, проще выпилить каплю с рабочего китайского донора.

Оффлайн SEGA-man

  • Пользователь
  • Сообщений: 61
  • Пол: Мужской
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #2 : 20 Ноябрь 2025, 21:21:54 »
Думаю стоит, выпиливать каплю и резать текстолит зачем? Еще надо рабочую плату найти.
А так, купил на алишке разбери зеро за 150р, залил код и запаял вместо капли.
Тем более, что эта проблема, когда капля отмирает частая, и думаю многим пригодится решение на разбери зеро судя по посту в Дзене :)

Оффлайн Фамиклон

  • Пользователь
  • Сообщений: 1188
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #3 : 21 Ноябрь 2025, 19:47:54 »
Тем более, что эта проблема, когда капля отмирает частая, и думаю многим пригодится решение на разбери зеро судя по посту в Дзене :)
Про Дзен конечно улыбнуло. Не буду говорить о том, что по многим авторам статей там клиника плачет, но, тут у нас 30 подписчиков, 600 просмотров за три года. А точно падёж джоев прям массовая проблема? Совершенно ничего не имею против энтузиазма во всех проявлениях, но с практичной точки зрения человек всегда выберет наиболее простой и доступный вариант.
Еще надо рабочую плату найти.
На Али примерно от 350 рубасов, мне кажется, не так уж велика цена.

Оффлайн Nhisti

  • Пользователь
  • Сообщений: 1081
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #4 : 22 Ноябрь 2025, 17:59:59 »
Я бы понял так заморачиваться с оригинальным контроллером, они нынче стоят как чугунный мост, особенно шестикнопочники, тут же проще новый купить.

Оффлайн SEGA-man

  • Пользователь
  • Сообщений: 61
  • Пол: Мужской
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #5 : 23 Ноябрь 2025, 00:13:52 »
На Али примерно от 350 рубасов, мне кажется, не так уж велика цена.

Так я ж видел качество этих джойстиков и могу сравнить новодельный клон и стародельный. Стародельные клоны, как в моем случае, часто имели хорошие провода и крестовину.


Добавлено позже:
Так я ж видел качество этих джойстиков и могу сравнить новодельный клон и стародельный. Стародельные клоны, как в моем случае, часто имели хорошие провода и крестовину.
ну вот тебе и юзкейс, как говорится) Сможешь восстановить оригинальный джой. А я в данном случае хочу восстановить хороший клон

Оффлайн Фамиклон

  • Пользователь
  • Сообщений: 1188
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #6 : 24 Ноябрь 2025, 19:54:19 »
Так я ж видел качество этих джойстиков и могу сравнить новодельный клон и стародельный. Стародельные клоны, как в моем случае, часто имели хорошие провода и крестовину.
Дык я ж не предлагаю на замену, я предлагаю в качестве донора капли, секрет которой известен сеговцам и китайцам.

Оффлайн Sanyameloman

  • Пользователь
  • Сообщений: 370
  • Он же Shurrick
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #7 : 25 Ноябрь 2025, 23:20:51 »
Цитата
А я в данном случае хочу восстановить хороший клон

По-моему, на том же "Водолее" продаются в том числе и хорошие платы для хороших клонов. Но, опять же - безумству храбрых поём мы песню :)
Только внимательно и проверять лучше на чём-нибудь, что не так жалко будет ежели что)

Оффлайн SEGA-man

  • Пользователь
  • Сообщений: 61
  • Пол: Мужской
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #8 : 05 Декабрь 2025, 21:08:32 »
О чем вообще разговор? Ну покупайте эти платы и пилите текстолит сами. Зачем тут это флуд?

Оффлайн Sanyameloman

  • Пользователь
  • Сообщений: 370
  • Он же Shurrick
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #9 : 05 Декабрь 2025, 22:39:38 »
Ну покупайте эти платы и пилите текстолит сами. Зачем тут это флуд?
Может, из-за того, что название данной темы носит общий характер, а не сфокусировано только на восстановлении геймпада Атмегой, "Малиной" или чем-то ещё? :)
Люди предлагают варианты - изощрённые, конечно, но вполне логичные (для поставленной задачи) и экономичные.
Я же платы предлагал не для пилежа, а для полноценной замены неисправной (те платы такого же размера).
Лично мне интересно найти "вундермикруху", как на фото внизу. Плата из относительно свежего джоя для мега драйва, но в дизайне Сега Сатурн (даже вторую кнопку Mode сделали :biggrin:).
Поиск по обозначению на этом чипе ничего не дал - а жаль... А ведь такая микруха могла бы решить и вашу проблему (если, конечно, у вас не стоит задача восстановить геймпад именно путём программирования микроконтроллера/микрокомпьютера).
« Последнее редактирование: 05 Декабрь 2025, 23:11:38 от Sanyameloman »

Оффлайн DaemoniX

  • Пользователь
  • Сообщений: 78
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #10 : 06 Декабрь 2025, 10:58:20 »
Такая микра и в геймпадах с переключателем на турбо была, но сейчас и там ничтожный шанс её найти, если брать новым. Только если на барахолках поиграть в лотерею.
Да и в обычных с надписью 16-bit могла попадаться.

Оффлайн Sanyameloman

  • Пользователь
  • Сообщений: 370
  • Он же Shurrick
    • Просмотр профиля
Re: Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #11 : 06 Декабрь 2025, 22:23:31 »
Такая микра и в геймпадах с переключателем на турбо была
Что любопытно, применимо к шестикнопочному джою мега драйва нигде не нашёл полноценного решения на элементной базе - везде попадаются какие-то оговорки и "нюансы". Либо решения для трёхкнопочного джоя, либо для шестикнопочного с кучей логики, который при всём при этом может неадекватно работать с "трёхкнопочными" играми (схема внизу с доп. переключателем - сам не проверял). Хотя, казалось бы, для той же сеги сатурн, как выяснилось, проблема решается всего двумя 74HC153.

Оффлайн Nhisti

  • Пользователь
  • Сообщений: 1081
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #12 : 07 Декабрь 2025, 16:09:17 »
может неадекватно работать с "трёхкнопочными" играми
Именно для этого и существует кнопка Mode

Оффлайн Sanyameloman

  • Пользователь
  • Сообщений: 370
  • Он же Shurrick
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #13 : 07 Декабрь 2025, 17:45:14 »
Именно для этого и существует кнопка Mode
Вот по идее да - для запуска той же Golden Axe надо зажать MODE перед включением питания приставки, чтоб включить трёхкнопочный режим. Прям хоть проверь схемку-то :D
(И да: ясень пень, что китайщину так восстанавливать нафиг не надо - чисто "научный" интерес так сказать :))

Оффлайн RafGul

  • Пользователь
  • Сообщений: 197
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #14 : 29 Декабрь 2025, 06:59:31 »
Такая микра и в геймпадах с переключателем на турбо была, но сейчас и там ничтожный шанс её найти, если брать новым. Только если на барахолках поиграть в лотерею.
Да и в обычных с надписью 16-bit могла попадаться.

У этой микросхемы пины не совпадают с выводами 315-5638, кнопки x, y, z, A, B, C замыкаются с землёй ч/з сопротивление 3,3кОм. Версия с турбо имеется ввиду.
« Последнее редактирование: 29 Декабрь 2025, 07:06:17 от RafGul »

Оффлайн RafGul

  • Пользователь
  • Сообщений: 197
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #15 : 30 Декабрь 2025, 10:26:10 »
Может кому-то довелось скачать код для атмеги8 из этой статьи: https://dzen.ru/a/Y4HEsPHGXi7GqIZL

Автор обновил ссылку!
На всякий случай:

Оффлайн SEGA-man

  • Пользователь
  • Сообщений: 61
  • Пол: Мужской
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #16 : 30 Декабрь 2025, 23:42:26 »
Да, обновил но я чет не разобрался со сборкой, поэтому через ИИ сделал кода на Си.
Прикрепил архив с файлом.

У меня пока нет возможности его затестить, но может кто попробует и отпишет?
Он совместим с atmega88
« Последнее редактирование: 18 Январь 2026, 23:20:12 от SEGA-man »

Оффлайн SEGA-man

  • Пользователь
  • Сообщений: 61
  • Пол: Мужской
    • Просмотр профиля
Восстановление геймпада (клона) от Sega Mega Drive 2
« Ответ #17 : 28 Январь 2026, 22:36:06 »
Прочитав статьи по данной тематике, как например здесь и при помощи ИИ, мне удалось написать код на С который легко можно залить через 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();
    }
}