vault backup: 2025-04-18 21:50:48
This commit is contained in:
6
.obsidian/workspace.json
vendored
6
.obsidian/workspace.json
vendored
@@ -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",
|
||||
|
||||
142
PERSONAL PROJECTS/PS1 DMA CD-ROM.md
Normal file
142
PERSONAL PROJECTS/PS1 DMA CD-ROM.md
Normal 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**: Привод тратит **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*! 📀
|
||||
Reference in New Issue
Block a user