6.2 KiB
6.2 KiB
VBlank (Vertical Blanking) в PlayStation 1
VBlank (вертикальное гашение) — это критически важный механизм синхронизации в PS1, связанный с выводом изображения на экран. Он используется для корректного обновления кадров, предотвращения артефактов рендеринга и эффективного управления ресурсами системы.
1. Что такое VBlank?
Физическая основа
- ЭЛТ-мониторы (как и TV, для которых создавалась PS1) рисуют изображение построчно, сверху вниз.
- VBlank — это промежуток времени между окончанием вывода последней строки кадра и началом вывода первой строки следующего кадра.
- В PS1 длительность VBlank:
- NTSC: ~1.23 мс (каждые 16.68 мс при 60 Гц).
- PAL: ~1.25 мс (каждые 20 мс при 50 Гц).
2. Как VBlank используется в PS1?
2.1. Синхронизация вывода изображения
- GPU PS1 рисует кадр в кадровый буфер (часть VRAM).
- Во время VBlank видеоконтроллер переключается на готовый кадр, избегая "разрывов" (tearing).
2.2. Безопасное обновление графики
- Любые изменения VRAM (загрузка текстур, обновление спрайтов) должны выполняться только во время VBlank, иначе:
- Возникают артефакты (мелькание, частичное обновление).
- Возможны конфликты доступа к VRAM между GPU и CPU.
2.3. Оптимизация работы CPU
- Игры используют VBlank как метку времени для:
- Обновления игровой логики (физика, AI).
- Загрузки данных с CD-ROM.
- Подготовки следующего кадра.
3. Техническая реализация VBlank
3.1. Прерывание VBlank
- При наступлении VBlank генерируется прерывание (IRQ0).
- CPU может обработать его, выполнив критически важные задачи.
Пример кода (обработка прерывания):
; Установка обработчика VBlank
la t0, vblank_handler ; Адрес обработчика
sw t0, 0x10000080 ; Запись в вектор прерываний
; Включение прерываний
mfc0 t1, $12 ; Статусный регир COP0
ori t1, 0x01 ; Разрешить IRQ0
mtc0 t1, $12
3.2. Регистры, связанные с VBlank
| Адрес | Назначение |
|---|---|
| 0x1F801070 | I_STAT — Флаги прерываний (бит 0 = VBlank). |
| 0x1F801100 | GPU STATUS — Содержит флаг VRAM_READY (можно ли обновлять VRAM). |
3.3. Ожидание VBlank в коде
#include <libgte.h>
#include <libgpu.h>
void wait_vblank() {
VSync(0); // Ожидание следующего VBlank
}
4. Практическое применение в играх
4.1. Двойная буферизация
- Буфер A выводится на экран.
- Буфер B рисуется GPU во время кадра.
- Во время VBlank буферы меняются местами (через
DrawSync(0)).
4.2. Загрузка данных
- CD-ROM и DMA активны преимущественно во время VBlank, чтобы не мешать рендерингу.
4.3. Лимит FPS
- Большинство игр PS1 работают на 50/60 FPS (частота VBlank), так как:
- Новый кадр начинается только после VBlank.
- Попытка рендерить быстрее бессмысленна (ЭЛТ не успеет отобразить).
5. Пример: Цикл рендеринга с VBlank
while (1) {
// 1. Ожидаем VBlank
VSync(0);
// 2. Обновляем игровую логику
update_game();
// 3. Готовим кадр в заднем буфере
render_frame();
// 4. Меняем буферы
SwapBuffers();
}
6. Интересные нюансы
- Режимы видео:
- NTSC (60 Гц) даёт более плавный геймплей, но меньше времени на VBlank.
- PAL (50 Гц) имеет более длинный VBlank, но ниже FPS.
- Overclocking: Некоторые домашние разработчики нарушают синхронизацию для экспериментов (рискуя артефактами).
7. Итог
- VBlank — это "пауза" между кадрами, используемая для:
- Синхронизации вывода изображения.
- Обновления графики без артефактов.
- Оптимизации загрузки данных.
- Без VBlank игры PS1 выглядели бы с глюками (как на многих эмуляторах без корректной синхронизации).
Для глубокого понимания изучите:
- PSX SPX Technical Reference
- LibGPU Documentation (PsyQ SDK).
Это ключ к плавной графике в играх вроде Crash Bandicoot или Tekken 3! 🎮