From f72bc1285d325599c9361ac34a3c7c1516db24c7 Mon Sep 17 00:00:00 2001 From: sShemet Date: Fri, 18 Apr 2025 23:50:59 +0500 Subject: [PATCH] vault backup: 2025-04-18 23:50:59 --- .obsidian/workspace.json | 10 +- PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md | 221 +++++++++++++++++++++++++ PERSONAL PROJECTS/PS1 DOCS/Untitled.md | 0 3 files changed, 226 insertions(+), 5 deletions(-) create mode 100644 PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md create mode 100644 PERSONAL PROJECTS/PS1 DOCS/Untitled.md diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 4728a2e..6ac0eab 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -41,12 +41,12 @@ "state": { "type": "markdown", "state": { - "file": "PERSONAL PROJECTS/PS1 DOCS/PS1 Geometry Transformation Engine.md", + "file": "PERSONAL PROJECTS/PS1 DOCS/Untitled.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "PS1 Geometry Transformation Engine" + "title": "Untitled" } } ], @@ -207,8 +207,10 @@ }, "active": "dd912cc876184c4f", "lastOpenFiles": [ - "PERSONAL PROJECTS/PS1 DOCS/LZSS C++ Lib.md", + "PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md", + "PERSONAL PROJECTS/PS1 DOCS/Untitled.md", "PERSONAL PROJECTS/PS1 DOCS/PS1 Geometry Transformation Engine.md", + "PERSONAL PROJECTS/PS1 DOCS/LZSS C++ Lib.md", "PERSONAL PROJECTS/PS1 DOCS/PS1 Ordering table.md", "PERSONAL PROJECTS/PS1 DOCS", "PERSONAL PROJECTS/PS1 DOCS/PSX code texture load unpack show and fade.md", @@ -241,8 +243,6 @@ "WORK & PROJECTS/Mol/Планы и диаграммы/СМК.md", "WORK & PROJECTS/Mol/Планы и диаграммы/Alfa Cloud/Alfa cloud readme.md", "WORK & PROJECTS/Mol/Планы и диаграммы/Alfa Cloud", - "WORK & PROJECTS/Mol/Серверы/git.moldev.ru.md", - "WORK & PROJECTS/Ulab/передача сформированных заявки и протокола как ссылку или файл.md", "Структура объектов испытаний.png", "Схема связей юрлиц и адресов.png", "Структура объектов испытаний.png.0.pdnSave", diff --git a/PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md b/PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md new file mode 100644 index 0000000..f973f93 --- /dev/null +++ b/PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md @@ -0,0 +1,221 @@ +### **Прерывания (Interrupts) на PlayStation 1: Зачем они нужны и как работают?** +Прерывания в PS1 — это механизм, позволяющий процессору **мгновенно реагировать** на критичные события (например, завершение рендеринга кадра или чтение с диска), не требуя постоянного опроса (polling). Они играют ключевую роль в синхронизации и эффективности системы. + +--- + +## **1. Основные типы прерываний** +В PS1 есть несколько аппаратных прерываний, каждое обслуживает свою задачу: + +| Прерывание | Источник | Задача | +|------------|---------------------------|-----------------------------------------------------------------------| +| **IRQ0** | VBlank (вертикальная синхронизация) | Оповещает о завершении рендеринга кадра. Используется для обновления графики. | +| **IRQ1** | GPU | Генерируется при ошибках GPU (например, переполнение буфера команд). | +| **IRQ2** | CD-ROM | Сигнализирует о завершении чтения данных с диска. | +| **IRQ3** | DMA | Уведомляет о завершении передачи данных (например, в VRAM). | +| **IRQ4** | Timer (таймер) | Используется для точного измерения времени. | +| **IRQ5** | Контроллеры (геймпады) | Обработка ввода игрока. | +| **IRQ6** | SPU (звук) | Прерывание от звукового процессора (например, окончание воспроизведения сэмпла). | + +--- + +## **2. Зачем они нужны?** +### **(1) Синхронизация графики (VBlank)** +Без прерывания **IRQ0** (VBlank) игра не могла бы: +- Плавно обновлять кадры (без разрывов изображения). +- Безопасно изменять VRAM (иначе артефакты). + +**Пример кода:** +```mips +wait_vblank: + li $t0, 0x1F801070 # I_STAT (регистр статуса прерываний) + lw $t1, 0($t0) + andi $t1, 0x1 # Проверяем бит IRQ0 (VBlank) + beqz $t1, wait_vblank + nop + jr $ra +``` + +--- + +### **(2) Асинхронная работа с CD-ROM** +Прерывание **IRQ2** позволяет: +- Читать данные с диска **без блокировки основного цикла игры**. +- Загружать уровни/аудио **в фоне**. + +**Пример:** +```mips +cd_read_done: + # IRQ2 вызвано — данные готовы + la $t0, cd_buffer + sw $t0, 0x1F8010A0 # DMA CD-ROM + jr $ra +``` + +--- + +### **(3) Обработка ввода (геймпады)** +Прерывание **IRQ5** сообщает: +- Когда игрок нажал кнопку (без задержек). +- Поддерживает **вибрацию** (если есть DualShock). + +**Пример:** +```mips +read_pad: + li $t0, 0x1F801040 # SIO_DATA + lw $t1, 0($t0) # Чтение кнопок + andi $t1, 0xFF // Фильтруем биты + jr $ra +``` + +--- + +## **3. Как работают прерывания?** +1. **Аппаратное событие** (например, завершение VBlank) устанавливает флаг в **I_STAT (0x1F801070)**. +2. Процессор **приостанавливает текущий код** и переходит к **обработчику прерывания** (адрес задаётся в **$k0**). +3. Обработчик: + - Сохраняет регистры в стек. + - Выполняет нужные действия (например, обновляет графику). + - Очищает флаг прерывания. + - Восстанавливает регистры и возвращает управление. + +**Пример обработчика на ассемблере:** +```mips +irq_handler: + addiu $sp, -32 # Резервируем стек + sw $ra, 0($sp) # Сохраняем $ra + sw $a0, 4($sp) # Сохраняем аргументы + + # Проверяем источник прерывания + li $t0, 0x1F801070 + lw $t1, 0($t0) + andi $t2, $t1, 0x1 # IRQ0 (VBlank)? + bnez $t2, handle_vblank + nop + + # Выход + lw $a0, 4($sp) + lw $ra, 0($sp) + addiu $sp, 32 + eret # Возврат из прерывания + +handle_vblank: + # Обновляем кадр + jal update_graphics + nop + j irq_handler # Возврат +``` + +--- + +## **4. Почему без прерываний — плохо?** +- **Графика**: Без VBlank появится **tearing** (разрывы кадров). +- **Звук**: SPU будет работать с задержками. +- **Ввод**: Кнопки станут «лагающими». +- **CD-ROM**: Игра зависнет на время загрузки. + +--- + +## **5. Итог** +Прерывания в PS1 — это **«нервная система» консоли**, которая: +1. **Синхронизирует** графику, звук, ввод и загрузку данных. +2. **Избегает busy-waiting** (постоянного опроса), экономя ресурсы CPU. +3. **Гарантирует точность** (например, 60 FPS через VBlank). + +Если ты **пишешь на ассемблере**, прерывания придётся обрабатывать вручную. В **C** этим частично занимается PsyQ SDK. + +P.S. В твоём переводе Persona 2 прерывания **уже работают** — иначе игра бы просто не запустилась! 😉 Но если хочешь **добавить свои обработчики** (например, для кастомной загрузки), дай знать — помогу с кодом. + +------------------ + +### **Как работают прерывания на PlayStation 1: детальный разбор** + +Прерывания (IRQ) в PS1 — это механизм, позволяющий процессору R3000A мгновенно реагировать на аппаратные события. Вот их полный цикл работы: + +#### **1. Инициализация прерываний** +Перед использованием нужно: +- Задать адрес обработчика в **$k0** (регистр ядра) +- Разрешить нужные IRQ в регистре **I_MASK (0x1F801074)** + +```mips +setup_irq: + la $k0, irq_handler # Устанавливаем обработчик + li $t0, 0x1F801074 + li $t1, 0x0001 # Разрешаем только IRQ0 (VBlank) + sw $t1, 0($t0) + jr $ra +``` + +#### **2. Аппаратный триггер** +Когда происходит событие (например, VBlank): +1. CD-ROM контроллер/GPU устанавливает бит в **I_STAT (0x1F801070)** +2. Процессор проверяет: + - Разрешено ли это прерывание в **I_MASK** + - Не находится ли он уже в обработчике (бит **IEc** в регистре **SR**) + +#### **3. Переход в обработчик** +Если условия выполнены: +1. Процессор: + - Сохраняет **PC** и **SR** в специальных регистрах (**EPC**, **ErrorEPC**) + - Переходит в режим ядра (бит **KUc** = 0) + - Прыгает по адресу в **$k0** + +#### **4. Обработка прерывания** +Типичный обработчик: +```mips +irq_handler: + # 1. Сохраняем контекст + addiu $sp, -120 # Резервируем место для 30 регистров + sw $at, 0($sp) + sw $v0, 4($sp) + # ... сохраняем все используемые регистры + + # 2. Определяем источник + li $t0, 0x1F801070 + lw $t1, 0($t0) # Читаем I_STAT + + # 3. Обработка VBlank + andi $t2, $t1, 0x1 + beqz $t2, not_vblank + nop + jal handle_vblank + nop + +not_vblank: + # 4. Сбрасываем флаг прерывания + li $t3, 0xFFFF00FF # Маска для очистки + and $t1, $t1, $t3 + sw $t1, 0($t0) # Пишем обратно в I_STAT + + # 5. Восстанавливаем контекст + lw $at, 0($sp) + lw $v0, 4($sp) + # ... + addiu $sp, 120 + + # 6. Возврат + eret # Возврат с восстановлением SR и PC +``` + +#### **5. Возврат из прерывания** +Инструкция **eret**: +- Восстанавливает **PC** из **EPC** +- Восстанавливает **SR** (включая бит **IEc**) +- Возвращает процессор в пользовательский режим + +#### **6. Особенности PS1** +1. **Приоритеты**: Нет аппаратного приоритета - порядок обработки определяется программно +2. **Вложенность**: Новые прерывания блокируются, пока **IEc = 0** +3. **Задержки**: Минимальная задержка между прерываниями - 5 тактов + +#### **7. Реальный пример из PsyQ** +Обработчик VBlank в библиотеке **libgs**: +1. Сохраняет матрицу преобразования +2. Обновляет буферы GPU +3. Вызывает пользовательский callback + +#### **8. Оптимизации** +- **Короткие обработчики**: Не более 100 тактов +- **Минимальное сохранение**: Только используемые регистры +- **Аппаратное ускорение**: Для DMA используйте **D_ICR (0x1F8010F4)** + +Для отладки в no$psx используйте точки останова на записи в **I_STAT**! \ No newline at end of file diff --git a/PERSONAL PROJECTS/PS1 DOCS/Untitled.md b/PERSONAL PROJECTS/PS1 DOCS/Untitled.md new file mode 100644 index 0000000..e69de29