vault backup: 2025-04-18 21:50:48

This commit is contained in:
sShemet
2025-04-18 21:50:48 +05:00
parent d3698f56e1
commit 4de7cc7161
2 changed files with 145 additions and 3 deletions

View File

@@ -41,12 +41,12 @@
"state": {
"type": "markdown",
"state": {
"file": "PERSONAL PROJECTS/PS1 Gpu-DMA.md",
"file": "PERSONAL PROJECTS/PS1 DMA CD-ROM.md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
"title": "PS1 Gpu-DMA"
"title": "PS1 DMA CD-ROM"
}
}
],
@@ -208,6 +208,7 @@
"active": "dd912cc876184c4f",
"lastOpenFiles": [
"PERSONAL PROJECTS/LZSS C++ Lib.md",
"PERSONAL PROJECTS/PS1 DMA CD-ROM.md",
"PERSONAL PROJECTS/PS1 Gpu-DMA.md",
"WORK & PROJECTS/Mol/Ideas/Все идеи для Моли.md",
"WORK & PROJECTS/Mol/Серверы/mail.mol-soft.ru.md",
@@ -250,7 +251,6 @@
"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_canvas2doc-data/newdoc-node_9cf121717dbde800_fromCanvas.md",
"WORK & PROJECTS/Mol/Серверы/Alfa cloud prod.canvas",
"PERSONAL PROJECTS/P2EP/cdRead.canvas",
"P2EP/cdRead.canvas",

View File

@@ -0,0 +1,142 @@
В PlayStation 1 (PS1) чтение данных с CD-ROM действительно использует **DMA (Direct Memory Access)**, но с рядом особенностей, связанных с устройством привода и буферизацией. Разберём процесс детально.
---
## **1. Как устроено чтение с CD-ROM в PS1?**
CD-ROM в PS1 работает через **специализированный контроллер**, который управляет:
- **Механизмом привода** (позиционирование головки).
- **Декодированием данных** (коррекция ошибок, деинтерливинг).
- **Передачей данных в RAM** через DMA.
### **1.1. Основные шаги чтения:**
1. **Запрос сектора**: CPU указывает номер сектора (LBA — Logical Block Address).
2. **Поиск и чтение**: Привод физически находит сектор на диске.
3. **Декодирование**: Данные проходят через:
- **CIRC (Cross-Interleaved Reed-Solomon Code)** — исправление ошибок.
- **EDC/ECC (Error Detection/Correction)** — проверка целостности.
4. **Буферизация**: Данные временно хранятся в **буфере CD-ROM (32 КБ)**.
5. **Передача в RAM**: Через DMA-канал **CDROM (канал 3)**.
---
## **2. Роль DMA в чтении CD-ROM**
### **2.1. DMA-канал CD-ROM**
- **Канал 3** выделен специально для CD-ROM.
- **Режимы передачи**:
- **Пакетный (Burst)**: Чтение нескольких секторов подряд (быстрее).
- **Пошаговый (Single)**: Чтение по одному сектору (точнее).
### **2.2. Как CPU запускает DMA?**
1. **Настройка DMA**:
- Указывается **адрес в RAM** (куда копировать).
- Задаётся **размер блока** (обычно 2048 байт на сектор).
- Выбирается **режим** (например, `DMA_CDROM_READ`).
2. **Запуск чтения**:
```c
// Пример на PsyQ SDK
CdReadSector(1, 16, buffer); // Читать 16 секторов, начиная с LBA 1
CdReadSync(0); // Ожидать завершения
```
3. **Автоматическая передача**:
- DMA забирает данные из буфера CD-ROM и копирует в RAM без участия CPU.
---
## **3. Технические детали**
### **3.1. Размеры и форматы секторов**
- **Режим 1 (стандартный)**:
- **2048 байт** полезных данных.
- Используется для игр (например, `DATA.BIN`).
- **Режим 2 (XA)**:
- **2336 байт** (включая аудио/видео).
- Поддерживает ADPCM-аудио (например, CD-DA треки).
### **3.2. Буферизация и кэширование**
- **Буфер CD-ROM (32 КБ)**:
- Хранит **до 16 секторов** (Mode 1).
- DMA читает отсюда, пока привод ищет следующий сектор.
- **Программный кэш**:
- Многие игры кэшируют часто используемые данные в RAM (например, уровни).
---
## **4. Пример кода (PsyQ SDK)**
### **4.1. Чтение одного сектора**
```c
#include <libcd.h>
void read_sector() {
uint8_t buffer[2048]; // Буфер в RAM
CdlLOC loc; // Позиция на диске (LBA)
// Преобразуем LBA в формат MSF (Minutes:Seconds:Frames)
CdIntToPos(1, &loc); // LBA 1 → 00:02:00
// Запуск чтения
CdRead(1, &loc, CD_READ_SPEED, buffer);
CdReadSync(0); // Ждём завершения DMA
}
```
### **4.2. Чтение нескольких секторов с DMA**
```c
#define SECTORS_TO_READ 10
void read_multiple_sectors() {
uint8_t big_buffer[2048 * SECTORS_TO_READ];
CdRead(SECTORS_TO_READ, (CdlLOC*)0, CD_READ_SPEED, big_buffer);
// Проверяем статус DMA
while (CdReadSync(1) == 0) {
VSync(0); // Ожидание + синхронизация с кадром
}
}
```
---
## **5. Оптимизации и проблемы**
### **5.1. Задержки**
- **Seek Time**: Привод тратит **100300 мс** на поиск сектора.
- **Решение**: Чтение последовательных секторов (меньше скачков головки).
### **5.2. Ошибки чтения**
- **CRC-проверка**: Если данные повреждены, PS1 повторяет чтение.
- **Метки защиты**: Лицензионные диски имеют специальные метки (anti-piracy).
### **5.3. Потоковое чтение**
- **Игры с FMV** (например, *Metal Gear Solid*) используют **двойную буферизацию**:
- Пока DMA передаёт один буфер в RAM, CD-ROM заполняет второй.
---
## **6. Как DMA взаимодействует с CD-ROM?**
1. **CPU** отправляет команду `CdRead()`.
2. **CD-ROM контроллер** начинает чтение в свой буфер.
3. **DMA-контроллер** (канал 3) забирает данные из буфера CD-ROM и копирует в RAM.
4. **Прерывание** (`INT2`) сигнализирует о завершении.
---
## **7. Полезные регистры**
| Адрес | Назначение |
|---------------|-------------------------------------|
| `0x1F8010B0` | **DMA CD-ROM Control** (канал 3) |
| `0x1F801800` | **CD-ROM Command/Status** |
| `0x1F801802` | **CD-ROM Response FIFO** |
---
## **Итог**
- **DMA (канал 3)** используется для чтения данных с CD-ROM в RAM.
- **Буфер CD-ROM (32 КБ)** снижает нагрузку на привод.
- **Оптимизации**: Чтение последовательных секторов, кэширование.
- **Задержки** неизбежны из-за механического характера привода.
Для глубокого понимания изучите:
- [PSX CD-ROM Hardware Specs](http://problemkaputt.de/psx-spx.htm#cdromdrive)
- [PsyQ SDK Documentation](http://psx.arthus.net/sdk/PsyQ/DOCS/)
Это ключ к работе с дисками в стиле *Resident Evil* или *Final Fantasy VII*! 📀