Files
SergObsidian/PERSONAL PROJECTS/PS1 DOCS/PS1 DMA CD-ROM.md
2025-04-18 23:10:56 +05:00

142 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

В 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*! 📀