5.1 KiB
5.1 KiB
В PlayStation 1 (PS1) взаимодействие с контроллерами (геймпадами, мышками, световыми пистолетами и т.д.) осуществляется через порты ввода-вывода (I/O) и специализированные контроллеры SIO (Serial Input/Output). Вот детальное объяснение процесса:
1. Аппаратная основа
1.1. Порты контроллеров
- PS1 имеет два порта для подключения устройств (Multitap позволяет расширить до 4–8 игроков).
- Каждый порт использует протокол SPI (Serial Peripheral Interface) для обмена данными.
1.2. Регистры управления
Основные регистры для работы с контроллерами:
| Адрес | Назначение |
|---|---|
| 0x1F801040 | SIO_DATA — Данные для отправки/приёма. |
| 0x1F801044 | SIO_STAT — Статус операции (готовность, ошибки). |
| 0x1F801048 | SIO_MODE — Настройка режима (скорость, прерывания). |
| 0x1F801050 | SIO_CTRL — Управление передачей (старт/стоп). |
2. Протокол обмена данными
2.1. Формат команд
Контроллеры PS1 понимают 5-байтовые команды:
- Стартовый байт (
0x01) — начало передачи. - Команда (например,
0x42— запрос состояния кнопок). - Данные (зависит от типа устройства).
2.2. Пример запроса состояния кнопок
; 1. Запись команды в SIO_DATA
li t0, 0x1F801040
li t1, 0x01000042 // Старт (0x01) + команда (0x42)
sw t1, 0(t0)
; 2. Ожидание готовности
wait_ready:
lw t2, 0x1F801044(SIO_STAT)
andi t2, t2, 0x0002 // Проверка бита "Готов к передаче"
beqz t2, wait_ready
; 3. Чтение ответа (5 байт)
lw t3, 0x1F801040(SIO_DATA) // Первые 4 байта
lw t4, 0x1F801040(SIO_DATA) // Последний байт
3. Типы контроллеров и их ответы
3.1. Стандартный геймпад (Digital Pad)
- Команда:
0x42. - Ответ: 5 байт:
[0x41][0x5A][Кнопки 1][Кнопки 2][Аналоговые данные (если есть)] - Распаковка кнопок:
- Байт 3:
SELECT,L3,R3,START,UP,RIGHT,DOWN,LEFT. - Байт 4:
L2,R2,L1,R1,TRIANGLE,CIRCLE,CROSS,SQUARE.
- Байт 3:
3.2. Аналоговый джойстик (DualShock)
- Поддерживает вибрацию и аналоговые стики.
- Команды:
0x43— запрос аналоговых данных.0x4D— управление моторчиками.
4. Как игры обрабатывают ввод?
- Инициализация порта:
InitPad(1, 0, NULL, 0); // Порт 1, без буфера - Чтение состояния:
struct PadButtonStatus pad; ReadPadStatus(&pad, 0); // Чтение порта 1 - Проверка кнопок:
if (pad.buttons & PAD_CROSS) { // Кнопка CROSS нажата }
5. Прерывания и синхронизация
- Прерывание IRQ7 используется для обработки ввода.
- Игры часто опрашивают контроллеры во время VBlank, чтобы избежать задержек.
6. Псевдокод полного цикла
while (1) {
VSync(0); // Синхронизация с кадром
PollPad(); // Опрос контроллера
if (PAD_PRESSED(PAD_UP)) {
player_y--;
}
}
7. Интересные нюансы
- Light Gun (GunCon) требует строгой синхронизации с лучом ЭЛТ.
- Multitap усложняет протокол (нужно переключать устройства).
8. Полезные ссылки
Это основа для работы с любыми контроллерами PS1 — от классического геймпада до танцевальных ковриков! 🎮