Files
SergObsidian/PERSONAL PROJECTS/P2EP/pseudoCode/FUN_800453e0 SystemEventManager.md
2025-04-20 00:25:47 +05:00

193 lines
7.9 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.

Эта функция является **критически важным системным обработчиком ввода/вывода или управления состоянием** в игре для 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
- Своевременную обработку событий
- Корректную синхронизацию подсистем игры