vault backup: 2025-04-18 22:00:49

This commit is contained in:
sShemet
2025-04-18 22:00:49 +05:00
parent 4de7cc7161
commit 92b9a0ea9e
3 changed files with 300 additions and 6 deletions

View File

@@ -41,12 +41,12 @@
"state": {
"type": "markdown",
"state": {
"file": "PERSONAL PROJECTS/PS1 DMA CD-ROM.md",
"file": "PERSONAL PROJECTS/PS1 MDEC.md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
"title": "PS1 DMA CD-ROM"
"title": "PS1 MDEC"
}
}
],
@@ -207,9 +207,11 @@
},
"active": "dd912cc876184c4f",
"lastOpenFiles": [
"PERSONAL PROJECTS/LZSS C++ Lib.md",
"PERSONAL PROJECTS/PS1 DMA CD-ROM.md",
"PERSONAL PROJECTS/PS1 DMA.md",
"PERSONAL PROJECTS/PS1 MDEC.md",
"PERSONAL PROJECTS/PS1 Gpu-DMA.md",
"PERSONAL PROJECTS/PS1 DMA CD-ROM.md",
"PERSONAL PROJECTS/LZSS C++ Lib.md",
"WORK & PROJECTS/Mol/Ideas/Все идеи для Моли.md",
"WORK & PROJECTS/Mol/Серверы/mail.mol-soft.ru.md",
"WORK & PROJECTS/Mol/Документы для ТЗ ЛИМС/СМК/КУек_лист_10_ошибок_УД_скачивание.pdf",
@@ -249,8 +251,6 @@
"WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_da4380327e36e455_fromCanvas.md",
"WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_d0967a61e8872474_fromCanvas.md",
"WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_be85b0f0c9d7c5c9_fromCanvas.md",
"WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_b9a89b6c704bbab9_fromCanvas.md",
"WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_ac17a82fee50447b_fromCanvas.md",
"WORK & PROJECTS/Mol/Серверы/Alfa cloud prod.canvas",
"PERSONAL PROJECTS/P2EP/cdRead.canvas",
"P2EP/cdRead.canvas",

View File

@@ -0,0 +1,148 @@
### **DMA (Direct Memory Access) в PlayStation 1**
DMA в PS1 — это механизм, позволяющий устройствам (GPU, CD-ROM, SPU и др.) **передавать данные напрямую в RAM без участия CPU**. Это ускоряет работу системы, освобождая процессор для других задач.
---
## **1. Для чего нужен DMA в PS1?**
- **Ускорение передачи данных**: CPU (R3000A) слишком медленный для копирования больших объёмов данных.
- **Разгрузка CPU**: Позволяет играм одновременно:
- Рендерить графику (GPU).
- Загружать уровни с CD-ROM.
- Проигрывать музыку (SPU).
- **Параллельная работа устройств**: Например, CD-ROM может грузить данные, пока GPU рисует кадр.
---
## **2. Как работает DMA?**
### **2.1. Общий принцип**
1. **CPU настраивает DMA**: Указывает источник, приёмник и размер данных.
2. **DMA-контроллер берёт управление шиной**: CPU временно "засыпает".
3. **Данные копируются напрямую** из устройства в RAM (или наоборот).
4. **DMA завершает работу** и сообщает CPU через прерывание.
### **2.2. Регистры DMA**
Главный контроллер DMA находится по адресу **`0x1F8010F0`**, но каждый канал имеет свои регистры:
| Адрес | Назначение |
|----------------|--------------------------------|
| `0x1F8010F0` | **DPCR** (Управление каналами) |
| `0x1F8010F4` | **DICR** (Статус/прерывания) |
| `0x1F8010__` | Регистры конкретных каналов |
---
## **3. Каналы DMA и их назначение**
В PS1 есть **6 каналов DMA**, каждый закреплён за конкретным устройством:
| Канал | Устройство | Назначение |
|-------|------------|----------------------------------------------------------------------------|
| **0** | MDEC (IN) | Декодирование видео (например, FMV из MPEG). |
| **1** | MDEC (OUT) | Вывод декодированных данных. |
| **2** | GPU | Передача команд и данных в видеопроцессор (например, списки отображения). |
| **3** | CD-ROM | Чтение данных с диска. |
| **4** | SPU | Загрузка семплов и команд в звуковой процессор. |
| **5** | PIO (EXT) | Расширенный порт (редко используется). |
| **6** | OTC | Очистка RAM (используется для Ordering Table в GPU). |
---
## **4. Как настроить и запустить DMA?**
### **4.1. Общий алгоритм**
Для любого канала DMA нужно:
1. **Установить источник и приёмник**:
- Если передача **из RAM в устройство** (например, GPU):
- Источник: Адрес в RAM.
- Приёмник: Регистр устройства (например, `0x1F801810` для GPU).
- Если передача **из устройства в RAM** (например, CD-ROM):
- Источник: Данные устройства (буфер CD-ROM).
- Приёмник: Адрес в RAM.
2. **Задать размер блока** и режим DMA:
- Размер: Сколько слов (4 байта) передать.
- Режим:
- `0x01000000` — одношаговый (по одному слову).
- `0x01000200` — пакетный (пачками, быстрее).
3. **Включить канал** через **DPCR** и **DICR**.
---
### **4.2. Примеры кода**
#### **Пример 1: Передача данных в GPU (канал 2)**
```asm
; Настройка DMA для GPU
li a0, 0x1F8010A0 ; Адрес регистра DMA2 (GPU)
la a1, command_list ; Адрес данных в RAM
sw a1, 0(a0) ; Источник = command_list
li a0, 0x1F8010A4
li a1, 0x01000200 ; Размер + режим (пакетный)
sw a1, 0(a0)
li a0, 0x1F8010A8
li a1, 0x01000001 ; Включить DMA
sw a1, 0(a0)
```
#### **Пример 2: Чтение CD-ROM (канал 3)**
```c
#include <libcd.h>
void cd_read_sectors(int lba, int num_sectors, void *buffer) {
CdRead(num_sectors, (CdlLOC*)&lba, CD_READ_SPEED, buffer);
CdReadSync(0); // Ожидать завершения DMA
}
```
---
## **5. Важные нюансы**
### **5.1. Синхронизация**
- DMA работает **асинхронно**. Нужно ждать завершения:
- Через **прерывание** (если настроено в DICR).
- Через **опрос флага** (например, `CdReadSync` для CD-ROM).
### **5.2. Ограничения**
- **Размер блока**: Не более 64 КБ за одну передачу.
- **Выравнивание**: Адреса в RAM должны быть кратны 4.
### **5.3. Конфликты**
- Если два устройства пытаются использовать DMA одновременно, возможны **задержки**.
- Решение: планировать передачу данных между кадрами (например, в VBlank).
---
## **6. DMA и Ordering Table (GPU)**
Для 3D-рендеринга DMA используется для передачи **Ordering Table** (OT):
1. CPU формирует список примитивов в RAM.
2. DMA (канал 2) копирует OT в GPU.
3. GPU рендерит кадр, соблюдая порядок из OT.
**Пример очистки OT через DMA (канал 6)**:
```asm
li a0, 0x1F8010E0 ; DMA6 (OTC)
la a1, ot_buffer ; Адрес OT
sw a1, 0(a0)
li a0, 0x1F8010E4
li a1, 0x00010000 ; Размер (например, 256 слов)
sw a1, 0(a0)
li a0, 0x1F8010E8
li a1, 0x11000002 ; Режим: очистка OT
sw a1, 0(a0)
```
---
## **7. Итог**
- **DMA в PS1** — это ключевой механизм для быстрой передачи данных между устройствами и RAM.
- **6 каналов**, каждый закреплён за конкретным устройством (GPU, CD-ROM, SPU и др.).
- **Настройка** требует указания источника, приёмника и режима работы.
- **Оптимизация DMA** критична для производительности (например, загрузка уровней без лагов).
Для глубокого понимания изучите:
- [PSX DMA Hardware Specs](http://problemkaputt.de/psx-spx.htm#dmacontroller)
- [PsyQ SDK Docs](http://psx.arthus.net/sdk/PsyQ/DOCS/)
Это основа для создания плавных игр вроде *Crash Bandicoot* или *Tekken 3*! 🚀

View File

@@ -0,0 +1,146 @@
Рендеринг потокового видео (FMV, Full Motion Video) на PlayStation 1 — это сложный процесс, сочетающий чтение данных с CD-ROM, декодирование через MDEC (Motion DECoder) и вывод на экран через GPU. Вот пошаговое объяснение:
---
### **1. Подготовка данных на диске**
- Видео хранится в специальном формате **STR** (Sony's Video Format), который содержит:
- **Видеопоток** — сжатый через MPEG-1 (но упрощённый для PS1).
- **Аудиопоток** — ADPCM или CD-DA (Red Book Audio).
- **Субтитры/тайминг** — дополнительные данные.
Данные разбиты на **секторы CD-ROM (Mode 2 XA)**, где чередуются видео и аудио.
---
### **2. Загрузка данных с CD-ROM**
1. **CPU отправляет команду чтения**:
```c
CdReadSector(/*Сектор начала*/, /*Кол-во секторов*/, /*Буфер в RAM*/);
```
2. **DMA (канал 3) копирует данные** из буфера CD-ROM в RAM:
- Используется **двойная буферизация**:
- Пока DMA заполняет **Буфер 1**, CPU/MDEC обрабатывает **Буфер 2**.
- Размер буфера обычно **1632 КБ** (816 секторов).
3. **Ожидание завершения**:
```c
CdReadSync(0); // Блокирующее ожидание
```
---
### **3. Декодирование видео через MDEC**
1. **CPU настраивает MDEC** (канал DMA 0/1):
- Указывает адрес сжатых данных в RAM.
- Запускает декодирование:
```asm
li t0, 0x1F801820 // MDEC_CMD
li t1, 0x60000000 // Команда "Decode Macroblock"
sw t1, 0(t0)
```
2. **MDEC декодирует MPEG-1**:
- Кадр разбит на **макроблоки 16x16**.
- Используется **DCT (Discrete Cosine Transform)** + **RLE (Run-Length Encoding)**.
- На выходе — **RGB16 (15-битный)** или **YUV** пиксели.
3. **DMA (канал 1) копирует результат** в RAM:
- Готовые кадры сохраняются в **отдельный буфер** (например, 320x240, 16-бит).
---
### **4. Вывод на экран через GPU**
1. **CPU отправляет кадр в VRAM**:
- Через DMA (канал 2) или вручную (порт `GP0`).
- Пример:
```asm
li a0, 0x1F8010A0 // DMA GPU (канал 2)
la a1, frame_buffer
sw a1, 0(a0) // Источник
li a1, 0x01000200 // Размер + режим
sw a1, 4(a0)
```
2. **GPU выводит кадр**:
- Используется **полноэкранный спрайт** (Rectangular Texture).
- Команда:
```asm
li t0, 0x1F801810 // GP0
li t1, 0xA0000000 // Команда "Draw Rectangle"
sw t1, 0(t0)
```
3. **Синхронизация с VBlank**:
- Чтобы избежать артефактов, обновление кадра происходит **во время VBlank**:
```c
VSync(0);
```
---
### **5. Аудиосопровождение**
- **ADPCM-аудио** декодируется через SPU (канал DMA 4):
```c
SpuSetTransferMode(SPU_TRANSFER_BY_DMA);
SpuWrite(audio_buffer, audio_size);
```
- **CD-DA (Red Book)** воспроизводится напрямую с диска (аппаратно).
---
### **6. Оптимизации**
1. **Чередование данных (Interleaving)**:
- Видео и аудио секторы чередуются на диске для плавности.
- Пример структуры:
```
[VIDEO] [AUDIO] [VIDEO] [AUDIO]...
```
2. **Предзагрузка**:
- Игры заранее грузят несколько кадров в память.
3. **Пропуск кадров**:
- Если декодирование не успевает, PS1 пропускает кадры (например, в Resident Evil).
---
### **7. Пример кода (упрощённый цикл FMV)**
```c
void play_fmv() {
uint8_t video_buffer[32768];
uint16_t frame_buffer[320*240];
while (!fmv_finished) {
// 1. Чтение с CD-ROM
CdReadSector(current_sector, 16, video_buffer);
CdReadSync(0);
// 2. Декодирование через MDEC
MDEC_DecodeFrame(video_buffer, frame_buffer);
// 3. Вывод через GPU
GPU_SendFrame(frame_buffer);
// 4. Синхронизация
VSync(0);
current_sector += 16;
}
}
```
---
### **8. Проблемы и ограничения**
- **Низкое разрешение**: 320x240 (чаще 256x224 для экономии памяти).
- **Цветовые артефакты**: Из-за 15-битного RGB.
- **Задержки**: Если CD-ROM не успевает, видео тормозит.
---
### **Итог**
1. **Чтение** с CD-ROM через DMA.
2. **Декодирование** через MDEC.
3. **Вывод** через GPU.
4. **Синхронизация** с VBlank.
Именно так работали FMV в играх вроде *Metal Gear Solid* и *Final Fantasy VII*! 🎥