Если отбросить многолетнюю истерию с предзаказами, пафосные трейлеры и культ «секретного железа», перед нами довольно заурядный битемап. Да, картинка на статичных скриншотах выглядит сочно, но стоит нажать Start — и иллюзия начинает рассыпаться.

Вот из чего на самом деле состоит эта «революция»:

  • Геймдизайн на уровне середняков из 90-х. По динамике, чувству удара и балансу Paprium не дотягивает до Streets of Rage 2 1992 года, не говоря уже о Comix Zone или Alien Soldier. Анимации местами дерганые, хитбоксы живут своей жизнью, а затянутые волны однотипных врагов утомляют.

  • Маркетинговый пузырь. Потенциальным покупателям годами продавали легенду про «80 мегабит чистой мощи» и таинственный сопроцессор Datenmeister, без которого бедная Сега якобы задохнулась бы от такой невероятной графики. На деле всё банальнее: внутри картриджа обычный 32-битный ARM-микроконтроллер и довольно сильная для одноигрового картриджа CPLD.

  • Железо ради защиты, не ради игры. Даже легендарный SVP в Virtua Racing честно молотил 3D-математику и конвертировал полигоны в тайлы для родного VDP, потому что Motorola 68000 такое бы не потянула. Здесь же у нас обычный 2D-битмап. Никакой «графической магии» Datenmeister не творит — картинку рисует VDP. А CPLD и ARM в картридже занимались декомпрессией, крутит внешний аудиопоток в обход консоли и городит лютую обфускацию шины, чтобы игру не сдампили.

  • Диагноз. Эта маркетинговая шелуха окончательно осыпалась в конце октября 2026 года, когда вышел патч Paprium MD. Энтузиасты просто выкинули весь этот зоопарк из ARM и хитрого маппера, пересадили звук на родной Z80 и уложили игру в обычный 15-мегабайтный ROM. И внезапно выяснилось: сама Mega Drive образца 1988 года прекрасно переваривает эту игру без костылей (если бы ещё YM в SEGA был бы 16-битный DAC, то разницы вообще бы не ощущалось).

Как это вообще работает:

Оригинал Paprium работает по принципу «тонкого клиента». Сама приставка Sega Mega Drive здесь выступает в роли видеоадаптера и контроллера ввода, а вся вычислительная работа перенесена внутрь картриджа на сопроцессор Datenmeister.

  • Общение через «почтовый ящик» (Dual-Port CPLD MAX10 RAM + SDRAM). Процессор консоли Motorola 68000 не имеет прямого доступа к сжатым ресурсам. Вместо этого он общается с картриджем через область общей памяти ($0-$1FFF DPRAM, $0x2000-$BFFF RO RAM, $C000-$FFFF Increments RAM, каждое чтение сдвигает pointer распаковщика на 2 байта) . Чтобы "отдать приказ", 68000 записывает аргументы в рабочие ячейки (например, 0x1E10–0x1E28) и отправляет код команды в управляющий регистр 0x1FEA. Пока чип занят, он выставляет биты занятости в статусном регистре 0x1FEA.

  • Аппаратный графический конвейер (DPRAM + SDRAM + VDP DMA). Внутри картриджа установлена SDRAM. По командам с приставки (0xAE — начало кадра, 0xAD — добавить объект, 0xAF — завершить кадр) ARM сопроцессор:

    1. Распаковывает тайлы алгоритмами LZ+RLE и LZO в SDRAM.

    2. Управляет кэшем слотов видеопамяти (VRAM) и при необходимости масштабирует графику (команды 0xF4/0xF5).

    3. Формирует готовую таблицу спрайтов (SAT) и готовые пакеты команд для VDP DMA. Приставке остается перегнать готовые данные в видеочип через окно потокового чтения 0xC000–0xFFFF и область 0x0-0xBFFF.

  • Аудиокодек (BGM + 8 каналов SFX). Штатные звуковые чипы Mega Drive (YM2612 и SN76489) в музыке не участвуют. Внутри картриджа работает программный декодер и 8-канальный микшер звуковых эффектов с поддержкой панорамирования, изменения высоты тона и стерео-эха. Готовый микс подмешивается напрямую на аудиовход слота картриджа.

Психология долгостроя: как покупателя заставили платить за DRM:

История разработки Paprium — это мастер-класс по манипуляции ожиданиями ретро-сообщества. Авторы годами подогревали ажиотаж, перенося релиз, рассказывая о «невозможных 80 мегабитах чистой мощи» и культивируя образ секретной технологии, которую «невозможно сэмулировать». Это чистая игра на психологии коллекционера: Вам продают не просто игру, а "артефакт" с уникальным чипом внутри.

Дефицит, закрытые предзаказы и мифы о «сгорающих при попытке дампа платах» создают вокруг посредственного битемапа ореол элитарности.

Тест №1. Запускаем оригинал на ПК (порт Datenmeister в Genesis Plus GX)

Чтобы детально изучить, как игра общается с картриджем, я портировал эмуляцию сопроцессора Datenmeister в эмулятор Genesis Plus GX.

Обработчик команд сопроцессора (регистр 0x1FEA):

static void paprium_cmd(uint16_t raw_data) {
    uint8_t cmd = raw_data >> 8;
    uint8_t arg = raw_data & 0xFF;
    uint16_t resp = 0;
    // Set BUSY 0x1FE4 / 0x1FE6
    ram_w16(0x1FE4, ram_r16(0x1FE4) | 0x0004);
    ram_w16(0x1FE6, ram_r16(0x1FE6) | (1 << 14));
    switch (cmd) {
    case 0x00:
        resp = (arg == 0xAA) ? 0x00FF : 0x0000;
        break;
    case 0x81: // Init / Reset
        ppm_vram_set_budget(0);
        ppm_obj_reset();
        break;
    case 0x84: // Mapper
        memcpy(ppm.ram + 0x8000, cart.rom + 0x8000, 0x8000);
        break;
    case 0x88: // Audio settings
        ppm.audio_flags = arg;
        ppm.ram[0x1801] = arg & 0x01;
        ppm.ram[0x1800] = ((arg & 0x01) ? 0x80 : 0x00) + ((arg & 0x02) ? 0x40 : 0x00);
        break;
    case 0x8C: // Play BGM
    {
        uint8_t track = arg & 0x7F;
        if (ppm.bgm_tracks_base_addr) {
            ppm_unpack(ppm_bgm_addr(track), ppm.bgm_unpack_addr);
        }
        if (track != 0) {
            paprium_load_mp3(track, 1);
        }
        else {
            ppm.music_track = 0;
        }
    }
    break;
    case 0x8D: // BGM settings
        if (arg == 0 || arg == 8) {
            ppm.music_track = 0;
        }
        break;
    case 0xAD: // Add object to draw list
        if (ppm.draw_list_ptr < ppm.draw_list + PPM_OBJECTS_COUNT) {
            *ppm.draw_list_ptr++ = arg;
        }
        break;
    case 0xAE: // Frame start
        ppm_obj_frame_start();
        break;
    case 0xAF: // Frame end (AF01 = обычный кадр, AF02 = кадр со скейлингом)
        ppm_obj_frame_end(arg);
        break;
    case 0xB0: // Sprite init
        memset(ppm.ram + 0x1F20, 0, 14 * 8);
        break;
    case 0xB1: // Sprite pause
        if (ram_r16(0x1F18) == 0) {
            memset(ppm.ram + 0xB00, 0, 8);
        }
        break;
    case 0xC6: // Setup data tables
        ppm_setup_data(
            ram_r32_swapped(0x1E10),
            ram_r32_swapped(0x1E14),
            ram_r32_swapped(0x1E18),
            ram_r32_swapped(0x1E1C),
            ram_r32_swapped(0x1E20),
            ram_r32_swapped(0x1E24),
            ram_r32_swapped(0x1E28)
        );
        break;
    case 0xC9: // BGM volume
        ppm.music_volume = arg;
        break;
    case 0xCA: // SFX volume
        ppm.sfx_volume = arg;
        break;
    case 0xD1: // SFX play
        paprium_sfx_play(arg);
        break;
    case 0xD2: // SFX stop
        paprium_sfx_stop(arg);
        break;
    case 0xD3: // SFX loop
        paprium_sfx_loop(arg);
        break;
    case 0xD5: // SFX stop all
        paprium_sfx_stop(0xC0);
        break;
    case 0xDA: // Unpack to SDRAM
    {
        uint32_t dst = ram_r16(0x1E10);
        uint32_t src = ((uint32_t)ram_r16(0x1E12) << 16) | ram_r16(0x1E14);
        ppm_unpack(src, dst);
        ppm.sdram_read_ptr = dst;
    }
    break;
    case 0xDB: // Set SDRAM read pointer
        ppm.sdram_read_ptr = ram_r32_swapped(0x1E10);
        break;
    case 0xDF: // EEPROM / SRAM read
    {
        uint16_t offset = ram_r16(0x1E10);
        if (arg >= 1 && arg <= 4) {
            memcpy(ppm.ram + offset, sram.sram + ((arg - 1) * 0x780), 0x780);
        }
    }
    break;
    case 0xE0: // EEPROM / SRAM write
    {
        uint16_t offset = ram_r16(0x1E12);
        if (arg >= 1 && arg <= 4) {
            memcpy(sram.sram + ((arg - 1) * 0x780), ppm.ram + offset, 0x780);
        }
        ram_w16(0x1FE6, ram_r16(0x1FE6) & ~((1 << 8) | (1 << 9)));
    }
    break;
    case 0xE7: // MegaWire fake ack
        ram_w16(0x1FE6, ram_r16(0x1FE6) | (1 << 5));
        ram_w16(0x1C00 + 0x10, ram_r16(0x1E10) + 16);
        break;
    case 0xEC: // VRAM block budget
        ppm_vram_set_budget(ram_r16(0x1E12));
        break;
    case 0xF2: // Unpack block (sprite test menu)
    {
        uint16_t blk = ram_r16(0x1E10);
        ppm_unpack(ppm_block_addr(blk), 0x9000);
        ppm_unpack(ppm_block_addr(blk), 0x9200);
        ppm.sdram_read_ptr = 0x9000;
    }
    break;
    case 0xF4: // Unpack scaling stamp
        ppm_unpack_internal(ram_r32_swapped(0x1E10), 0, 1);
        break;
    case 0xF5: // Rescale stamp
        ppm_stamp_rescale(
            ram_r16(0x1E10),
            ram_r16(0x1E12),
            ram_r16(0x1E14),
            ram_r16(0x1E16)
        );
        break;
    default:
        break;
    }
    // Снимаем флаг занятости и записываем ответ в 0x1FEA
    ram_w16(0x1FE4, ram_r16(0x1FE4) & ~0x0004);
    ram_w16(0x1FE6, ram_r16(0x1FE6) & ~(1 << 14));
    ram_w16(0x1FEA, resp & ~0x8000);
}

Смотрим, как доказательство концепта: https://archive.org/details/ppm-emu

Как запустить: скачиваем, распаковываем, запускаем ppm.cmd (windows).

Что я хочу сказать этим?

На борту CPLD MAX10 10M08 , 64к быстрой памяти внутри, 8000 логических блоков, 18×18 бит 16 независимых аппаратных блоков умножения, процессор CORTEX M-4, SDRAM и FLASH, при этом Z80 в консоли стоит, никаких вращений, только скалинг, распаковка и аудио! Динамическое освещение казалось бы тема, нет такого, вращение, 3D модели, нет такого, просто копирование того что распаковал ARM на экран через CPLD, с таким подходом SEGA CD выглядит супер мегахит, который не возможно реализовать в 90-х!

Тест №2. Оригинальный дамп на IVD6 MAX.

Теперь от программной эмуляции переходим к живому железу.

Берем оригинальную Sega Mega Drive, флеш-картридж InviteDRIVE v6 MAX и запускаем непатченный образ Paprium. Чтобы не тратить 2Gb памяти на карте, соберем паприум в пакованный образ для аппаратных картриджей SCDX с помощью вот этой утилиты: https://ivd6max.ramfactory.com/scdx.html.

PAPRIUM Оригинал

rutube.ru

Обратите внимание на звук на стартовой заставке: с первых секунд поверх интро начинает играть трек из меню выбора персонажей (*90's Acid Dub Character Select*), чего в оригинале не было.

Специально вшил этот трек на старт ради наглядной демонстрации: показать, что можно играть внешний цифровой аудиопоток поверх работающей картинки через слот картриджа — точно так же, как это делал «секретный» чип в оригинале.

Тест №3. Запуск 15-мегабайтного хака без спецчипа.

А теперь заливаем октябрьский патч Paprium MD на 15 мегабайт, из которого энтузиасты полностью вычистили зависимость от Cortex-M4 и внешнего аудиокодека.

Стандартное адресное пространство Sega Mega Drive ограничено окном в 4 мегабайта. Чтобы консоль увидела все 15 МБ разжатой графики и кода, в дело вступает аппаратный маппер банков SSF2 (Super Street Figher 2) памяти внутри ПЛИС картриджа.

И вот здесь всё встает на свои места: FPGA картриджа переключает банки памяти. Штатный Motorola 68000 сам справляется с переброской тайлов в VDP.

Звук полностью переехал на родные Z80 и YM2612: да, из-за ограничений ЦАП самого YM2612 он звучит проще, чем внешний поток с картриджа, но при этом абсолютно аутентично для классической Mega Drive.

Резюме История с Paprium — показательный пример того, как громкий маркетинг, искусственный дефицит и «секретный чип под эпоксидкой» могут годами продавать весьма посредственный битемап под видом технологической революции.

Когда же с проекта сняли шелуху в виде Cortex-M4 и MAX 10, выяснилось, что обычная Sega Mega Drive 1988 года легко тащит этот 15-мегабайтный объем сама — а при желании и внешний аудиопоток сверху накинет.

Поэтому для меня PAPRIUM это обман.

Еще раз повторюсь, это мое исключительно субъективное мнение! Я не настаиваю на нем, просто мнение.

За сим позвольте откланяться, С уважением, и наилучшими пожеланиями, наилучшего дня!

Спасибо!