Коллеги, зацепила эта тема. Подниму, пожалуй, несколько технических и исторических аспектов, которые могут прояснить картину «раскладочного хаоса» на клонах. Сам сталкивался и с железякой, и с необходимостью писать софт, который на всем этом работает.
1. Корень проблемы: не POKE, а IN/OUT
Когда говорят про POKE 23560, scancode — это грубое упрощение, работающее только в очень ограниченных случаях (обычно в BASIC-программах, эмулирующих нажатие). Настоящее чтение клавиатуры в машинном коде — это работа с портами #FE (и другими на клонах). Каждая половинка порта (верхние 5 бит адреса) выбирает одну из восьми линий матрицы 8x5.
На оригинальном Sinclair ZX Spectrum 48K схема сканирования была простой и элегантной: 8 линий на выход (A8-A15 шины адреса через дешифратор74LS138), 5 линий на вход (через буфер 74LS244). Раскладка была жестко зашита в эту матрицу и в ПЗУ процедуры чтения (#028E KEY_SCAN, #02BF KEY_TEST).
2. Почему на клонах всё «поплыло»?
Клоны (особенно советские/постсоветские) рождались в условиях дефицита оригинальных микросхем. Инженеры использовали то, что было:
· Другие дешифраторы и буферы. Менялась логика преобразования адреса порта в номер линии матрицы. Это первичный источник сдвига раскладки.
· Физическая перекоммутация клавиш. Чтобы хоть как-то соответствовать оригинальной карте символов, клавиши могли просто перепаять на другие линии матрицы. Поэтому на одном и том же клоне «ZX-Profy» у одного производителя могла быть одна раскладка, у другого — уже слегка измененная.
· Изменение процедуры чтения в ПЗУ (ROM). Самый радикальный, но и самый «правильный» с точки зрения совместимости путь. Если «железная» раскладка не совпадает с оригинальной, можно переписать драйвер клавиатуры в ПЗУ, чтобы он преобразовывал новые сканкоды в старые. Но для этого нужен был доступ к исходникам ПЗУ (редко) или мастерство в реверс-инжиниринге.
3. Практический вывод для программистов и пользователей эмуляторов
Если вы пишете код, который должен работать на реальном железе (демо, игра, утилита), особенно на клонах:
· Не используйте «магические» POKE для эмуляции ввода. Они ненадежны.
· Для чтения клавиш всегда вызывайте стандартную процедуру KEY_SCAN из ПЗУ (#028E). Она уже знает про раскладку данного конкретного клона (если ПЗУ было адаптировано).
· Если же вы пишете собственный драйвер ввода (например, для меню загрузчика или игры, работающей с отключенным ПЗУ), будьте готовы к тому, что вам понадобится несколько пресетов матриц для разных популярных клонов (Пентагон, Profi, Scorpion). Определять, какой пресет использовать, можно по OUT 7FFDh, A или другим признакам (например, по поведению порта #1FFD у 128K моделей).
4. Для владельцев конкретного железа (отвечая на вопросы в ветке)
Чтобы точно понять, какая у вас раскладка, нужен не большой софт, а минимальная тестовая программа на ассемблере.
1. Она должна в цикле опрашивать все возможные порты клавиатуры (#FEFE, #FDFE, ... #EFFE, #DFFE, ... — все 8x8=64 комбинации старших битов).
2. Для каждого нажатого порта выводить в каком-нибудь углу экрана значение этого порта (в двоичном или шестнадцатеричном виде).
3. Составить карту: нажимаете, например, «Q», видите, что сработал порт #FBFE и считан бит %xxxxx11101 (бит 0 = 0). Значит, эта клавиша сидит на линии A11=0 (порт #FB??) и входной линии D0.
Сопоставив эту карту с оригинальной матрицей Спектрума (есть в
www.wearmouth.demon.co.uk/zx82.htm ), вы сразу увидите сдвиг. Если сдвиг кратен степени двойки (например, все линии смещены на 1) — это проблема в дешифраторе. Если хаотично — это ручная перепайка.
Итог: «Раскладка» — это не абстракция, а прямое следствие схемотехники конкретной платы. И пока вы используете стандартные вызовы ПЗУ, проблема чаще всего решена создателями вашего клона. Проблемы начинаются при прямом доступе к портам или при запуске софта, написанного под «железную» матрицу другого клона.