vault backup: 2025-04-20 00:25:47
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
Эта функция является **критически важным системным обработчиком ввода/вывода или управления состоянием** в игре для PS1. Вот детальный разбор:
|
||||
|
||||
### 🔍 Основное назначение
|
||||
Функция управляет:
|
||||
1. **Очередью аппаратных событий** (контроллеры, таймеры, DMA)
|
||||
2. **Синхронизацией игрового состояния** между различными подсистемами
|
||||
3. **Обработкой ошибок** и аварийных сценариев
|
||||
|
||||
### 📌 Полная реконструкция на C
|
||||
```c
|
||||
#define HW_REG_BASE 0x1F801000 // Базовый адрес аппаратных регистров PS1
|
||||
|
||||
int SystemEventManager(int system_state)
|
||||
{
|
||||
// 1. Проверка условий для обработки основного события
|
||||
if (gSystemActive &&
|
||||
!system_state[0x37] &&
|
||||
!system_state[0x38] &&
|
||||
(system_state == *(int*)(system_state + 0x10) || !system_state[0x39]) &&
|
||||
!**(char**)(system_state + 0x30))
|
||||
{
|
||||
gEventCallback(system_state); // Обработка события
|
||||
}
|
||||
|
||||
// 2. Главный цикл обработки событий
|
||||
int retry_count = -1;
|
||||
if (gSystemActive)
|
||||
{
|
||||
int offset = -0xF0;
|
||||
do {
|
||||
gEventCounter--;
|
||||
if (gEventCounter < 1) break;
|
||||
|
||||
// Проверка вторичных условий
|
||||
if (retry_count >= 0)
|
||||
{
|
||||
int secondary_state = *(int*)(system_state + 0xC) + offset;
|
||||
if (!secondary_state[0x37] &&
|
||||
!secondary_state[0x38] &&
|
||||
(secondary_state == *(int*)(secondary_state + 0x10) || !secondary_state[0x39]) &&
|
||||
!**(char**)(secondary_state + 0x30))
|
||||
{
|
||||
gEventCallback(secondary_state);
|
||||
}
|
||||
}
|
||||
|
||||
// Обработка аппаратного события
|
||||
byte event_type = GetHardwareEvent(system_state, 1);
|
||||
int status = ProcessHardwareEvent(system_state, event_type);
|
||||
if (status < 0) return status;
|
||||
|
||||
// Ожидание готовности аппаратуры
|
||||
uint16_t* hw_status = (uint16_t*)(gHardwareRegs + 4);
|
||||
TIMER_CLOCK = GetSystemClock();
|
||||
*gControlReg = 0xFFFFFF7F;
|
||||
HW_TIMEOUT = 60;
|
||||
|
||||
while (*hw_status & 0x80) {
|
||||
status = CheckHardwareReady();
|
||||
if (status != 0) goto next_event;
|
||||
hw_status = (uint16_t*)(gHardwareRegs + 4);
|
||||
}
|
||||
|
||||
*hw_status |= 0x10; // Установка флага готовности
|
||||
retry_count++;
|
||||
offset += 0xF0;
|
||||
} while (retry_count < 4);
|
||||
}
|
||||
|
||||
// 3. Управление состоянием системы
|
||||
int state_index = 0;
|
||||
if (gEventCounter > 1)
|
||||
{
|
||||
dword* state_ptr = &gSystemStates[gActiveSubsystem == 0];
|
||||
int subsystem_offset = (gActiveSubsystem == 0) ? 0xF0 : 0;
|
||||
|
||||
do {
|
||||
dword current_state = *state_ptr;
|
||||
if ((int)current_state < 0) break;
|
||||
|
||||
if (current_state > 0) {
|
||||
int target_state = *(int*)(gStateBuffer + subsystem_offset + 0xC) + (current_state - 1) * 0xF0;
|
||||
gStateCallback(target_state);
|
||||
}
|
||||
|
||||
// Конечный автомат состояний
|
||||
switch(current_state) {
|
||||
case 3:
|
||||
gStateCallback(target_state - 0xF0);
|
||||
*state_ptr = 1;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
int base_state = gStateBuffer + subsystem_offset;
|
||||
gStateCallback(base_state);
|
||||
gSecondaryCallback(base_state);
|
||||
*state_ptr = -1;
|
||||
break;
|
||||
case 4:
|
||||
*state_ptr = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
// Дополнительная обработка
|
||||
event_type = GetHardwareEvent(system_state, gSystemActive);
|
||||
status = ProcessSecondaryEvent(system_state, event_type);
|
||||
if (status < 0) return status;
|
||||
|
||||
// Повторная проверка аппаратуры
|
||||
hw_status = (uint16_t*)(gHardwareRegs + 4);
|
||||
TIMER_CLOCK = GetSystemClock();
|
||||
*gControlReg = 0xFFFFFF7F;
|
||||
HW_TIMEOUT = 60;
|
||||
|
||||
while (*hw_status & 0x80) {
|
||||
status = CheckHardwareReady();
|
||||
if (status != 0) goto event_processed;
|
||||
hw_status = (uint16_t*)(gHardwareRegs + 4);
|
||||
}
|
||||
|
||||
*hw_status |= 0x10;
|
||||
gEventCounter--;
|
||||
} while (gEventCounter > 1);
|
||||
}
|
||||
|
||||
// 4. Финальная стадия обработки
|
||||
do {
|
||||
gEventCounter--;
|
||||
if (gEventCounter < 1) {
|
||||
while (!(*(uint16_t*)(gHardwareRegs + 4) & 2)); // Ожидание завершения
|
||||
byte* data_ptr = *(byte**)(system_state + 0x3C);
|
||||
data_ptr[*(byte*)(system_state + 0x44)++] = *(byte*)gHardwareRegs;
|
||||
gCompletionCallback(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
event_type = GetHardwareEvent(system_state, gSystemActive);
|
||||
status = ProcessSecondaryEvent(system_state, event_type);
|
||||
if (status < 0) return status;
|
||||
} while (*(short*)(gHardwareRegs + 0xE) != 0x22);
|
||||
|
||||
// ... (аналогичная обработка аппаратного статуса)
|
||||
}
|
||||
```
|
||||
|
||||
### 🔧 Ключевые особенности
|
||||
1. **Управление состоянием**:
|
||||
- Использует конечный автомат с состояниями 0-4
|
||||
- Обрабатывает как основные, так и вторичные события
|
||||
|
||||
2. **Аппаратная синхронизация**:
|
||||
- Работает с регистрами PS1 (0x1F801xxx)
|
||||
- Ожидает готовности аппаратуры через флаги
|
||||
- Управляет таймерами (TMR_SYSCLOCK_VAL)
|
||||
|
||||
3. **Обработка ошибок**:
|
||||
- Возвращает коды ошибок (-3 и другие)
|
||||
- Проверяет статус после каждой операции
|
||||
|
||||
4. **Оптимизации**:
|
||||
- Фиксированные смещения (0xF0 для блоков состояний)
|
||||
- Пакетная обработка событий
|
||||
|
||||
### 🌟 Практическое применение
|
||||
Эта функция может быть:
|
||||
1. **Драйвером контроллера**:
|
||||
- Обрабатывает ввод с геймпада
|
||||
- Управляет вибрацией и другими эффектами
|
||||
|
||||
2. **Менеджером DMA**:
|
||||
- Контролирует передачу данных
|
||||
- Обрабатывает прерывания
|
||||
|
||||
3. **Ядром аудиосистемы**:
|
||||
- Управляет SPU (звуковым процессором)
|
||||
- Синхронизирует аудиопотоки
|
||||
|
||||
### 📊 Структура данных
|
||||
```c
|
||||
// Пример системного состояния (0xF0 байт)
|
||||
struct SystemState {
|
||||
dword main_state; // 0x00: Основное состояние
|
||||
byte sub_state[0x34]; // 0x04: Внутренние флаги
|
||||
byte* data_buffer; // 0x38: Буфер данных
|
||||
byte data_index; // 0x3C: Индекс в буфере
|
||||
// ... другие поля ...
|
||||
};
|
||||
```
|
||||
|
||||
Эта функция - критически важный системный компонент, обеспечивающий:
|
||||
- Стабильную работу с аппаратурой PS1
|
||||
- Своевременную обработку событий
|
||||
- Корректную синхронизацию подсистем игры
|
||||
Reference in New Issue
Block a user