В 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 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**: Привод тратит **100–300 мс** на поиск сектора. - **Решение**: Чтение последовательных секторов (меньше скачков головки). ### **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*! 📀