vault backup: 2025-04-19 22:12:43

This commit is contained in:
sShemet
2025-04-19 22:12:43 +05:00
parent 668f5741ee
commit 56d6b75474
2 changed files with 203 additions and 4 deletions

View File

@@ -41,12 +41,12 @@
"state": {
"type": "markdown",
"state": {
"file": "PERSONAL PROJECTS/PS1 DOCS/fade calculation.md",
"file": "PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
"title": "fade calculation"
"title": "PS1 IRQ"
}
}
],
@@ -207,8 +207,8 @@
},
"active": "dd912cc876184c4f",
"lastOpenFiles": [
"PERSONAL PROJECTS/PS1 DOCS/PS1 Gamepad.md",
"PERSONAL PROJECTS/PS1 DOCS/fade calculation.md",
"PERSONAL PROJECTS/PS1 DOCS/PS1 Gamepad.md",
"PERSONAL PROJECTS/PS1 DOCS/PS1 Gpu-DMA.md",
"PERSONAL PROJECTS/PS1 DOCS/PS1 Ordering table.md",
"PERSONAL PROJECTS/PS1 DOCS/PS1 DMA.md",

View File

@@ -295,4 +295,203 @@ SetIntrMask(old_mask);
4. **Сочетание с обработчиками**: Даже если прерывание разрешено маской, для него должен быть установлен обработчик через соответствующие функции PsyQ.
Эта функция предоставляет низкоуровневый контроль над прерываниями и обычно используется в сочетании с более высокоуровневыми API PsyQ для управления конкретными типами прерываний.
Эта функция предоставляет низкоуровневый контроль над прерываниями и обычно используется в сочетании с более высокоуровневыми API PsyQ для управления конкретными типами прерываний.
---
Вот подробное объяснение работы прерываний в PlayStation 1 с примерами на ассемблере MIPS R3000, который используется в PS1:
## 1. Регистры прерываний
Основные регистры (все адреса в шестнадцатеричном формате):
```mips
li $t0, 0x1F801070 # I_STAT - статус прерываний
li $t1, 0x1F801074 # I_MASK - маска прерываний
```
## 2. Установка обработчика прерываний
Вектор прерываний находится по адресу 0x80000080. Пример установки обработчика:
```mips
.org 0x80000080 # Вектор прерываний
j my_irq_handler # Переход к обработчику
nop
my_irq_handler:
# Сохраняем регистры
addiu $sp, $sp, -32
sw $ra, 0($sp)
sw $a0, 4($sp)
sw $v0, 8($sp)
# Проверяем тип прерывания
lw $t0, 0x1F801070 # Читаем I_STAT
lw $t1, 0x1F801074 # Читаем I_MASK
and $t2, $t0, $t1 # Активные и разрешенные прерывания
# Обработка VBLANK
andi $t3, $t2, 0x1
beqz $t3, not_vblank
nop
# Код обработки VBLANK
jal handle_vblank
nop
not_vblank:
# Обработка других прерываний...
# Сброс флагов прерываний
sw $t0, 0x1F801070 # Записываем обратно в I_STAT
# Восстанавливаем регистры
lw $ra, 0($sp)
lw $a0, 4($sp)
lw $v0, 8($sp)
addiu $sp, $sp, 32
# Возврат из прерывания
eret
```
## 3. Включение прерываний
Пример настройки VBLANK прерывания:
```mips
# Разрешаем VBLANK в маске
li $t0, 0x1
sw $t0, 0x1F801074 # I_MASK
# Включаем прерывания глобально
mfc0 $t0, $12 # Читаем Status register
ori $t0, $t0, 0x1 # Разрешаем прерывания
mtc0 $t0, $12 # Записываем обратно
```
## 4. Обработка VBLANK
Пример обработчика вертикального гашения:
```mips
handle_vblank:
addiu $sp, $sp, -16
sw $ra, 0($sp)
# Инкрементируем счетчик кадров
la $t0, frame_counter
lw $t1, 0($t0)
addiu $t1, $t1, 1
sw $t1, 0($t0)
# Вызов C-функции
jal update_graphics
nop
lw $ra, 0($sp)
addiu $sp, $sp, 16
jr $ra
nop
```
## 5. Обработка контроллера
Пример обработки ввода с геймпада:
```mips
handle_controller:
addiu $sp, $sp, -16
sw $ra, 0($sp)
# Чтение состояния контроллера
li $t0, 0x1F801040 # JOY_DATA
lw $t1, 0($t0)
# Проверка кнопки START
andi $t2, $t1, 0x1000
beqz $t2, no_start
nop
# Обработка нажатия START
jal pause_game
nop
no_start:
lw $ra, 0($sp)
addiu $sp, $sp, 16
jr $ra
nop
```
## 6. Критические секции
Отключение/включение прерываний:
```mips
disable_interrupts:
mfc0 $t0, $12
li $t1, 0xFFFFFFFE
and $t0, $t0, $t1
mtc0 $t0, $12
jr $ra
nop
enable_interrupts:
mfc0 $t0, $12
ori $t0, $t0, 0x1
mtc0 $t0, $12
jr $ra
nop
```
## 7. Таймеры
Настройка таймера 0:
```mips
setup_timer0:
# Устанавливаем период (1/60 секунды для NTSC)
li $t0, 0x1F801100
li $t1, 0x0000
sw $t1, 0($t0) # TIMER0_COUNTER
li $t1, 0x03FF
sw $t1, 4($t0) # TIMER0_MODE
li $t1, 0x0100
sw $t1, 8($t0) # TIMER0_TARGET
# Разрешаем прерывание таймера
li $t0, 0x1F801074
lw $t1, 0($t0)
ori $t1, $t1, 0x10 # BIT 4 - TIMER0
sw $t1, 0($t0)
jr $ra
nop
```
## Важные замечания:
1. Все обработчики должны:
- Сохранять/восстанавливать регистры
- Быть максимально быстрыми
- Сбрасывать флаги прерываний
2. Для работы с прерываниями в C через PsyQ SDK используются:
```c
SetIntrMask(0x400); // Разрешить прерывания
EnterCriticalSection(); // Запретить прерывания
ExitCriticalSection(); // Разрешить прерывания
```
3. Стандартная инициализация в PsyQ:
```c
ResetCallback();
SetIntrHandler(MyHandler);
```
Эти примеры демонстрируют низкоуровневую работу с прерываниями на ассемблере MIPS R3000, который используется в PlayStation 1. В реальных проектах часто используют комбинацию ассемблера и C для удобства.