From 92b9a0ea9e0d7069547bd3ccc93351245b21e806 Mon Sep 17 00:00:00 2001 From: sShemet Date: Fri, 18 Apr 2025 22:00:49 +0500 Subject: [PATCH] vault backup: 2025-04-18 22:00:49 --- .obsidian/workspace.json | 12 +-- PERSONAL PROJECTS/PS1 DMA.md | 148 ++++++++++++++++++++++++++++++++++ PERSONAL PROJECTS/PS1 MDEC.md | 146 +++++++++++++++++++++++++++++++++ 3 files changed, 300 insertions(+), 6 deletions(-) create mode 100644 PERSONAL PROJECTS/PS1 DMA.md create mode 100644 PERSONAL PROJECTS/PS1 MDEC.md diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 90939bc..165b53a 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -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", diff --git a/PERSONAL PROJECTS/PS1 DMA.md b/PERSONAL PROJECTS/PS1 DMA.md new file mode 100644 index 0000000..3906dd7 --- /dev/null +++ b/PERSONAL PROJECTS/PS1 DMA.md @@ -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 + +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*! 🚀 \ No newline at end of file diff --git a/PERSONAL PROJECTS/PS1 MDEC.md b/PERSONAL PROJECTS/PS1 MDEC.md new file mode 100644 index 0000000..f7b561f --- /dev/null +++ b/PERSONAL PROJECTS/PS1 MDEC.md @@ -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**. + - Размер буфера обычно **16–32 КБ** (8–16 секторов). + +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*! 🎥 \ No newline at end of file