vault backup: 2025-04-19 22:12:43
This commit is contained in:
6
.obsidian/workspace.json
vendored
6
.obsidian/workspace.json
vendored
@@ -41,12 +41,12 @@
|
|||||||
"state": {
|
"state": {
|
||||||
"type": "markdown",
|
"type": "markdown",
|
||||||
"state": {
|
"state": {
|
||||||
"file": "PERSONAL PROJECTS/PS1 DOCS/fade calculation.md",
|
"file": "PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md",
|
||||||
"mode": "source",
|
"mode": "source",
|
||||||
"source": false
|
"source": false
|
||||||
},
|
},
|
||||||
"icon": "lucide-file",
|
"icon": "lucide-file",
|
||||||
"title": "fade calculation"
|
"title": "PS1 IRQ"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -207,8 +207,8 @@
|
|||||||
},
|
},
|
||||||
"active": "dd912cc876184c4f",
|
"active": "dd912cc876184c4f",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 Gamepad.md",
|
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/fade calculation.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 Gpu-DMA.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 Ordering table.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 Ordering table.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 DMA.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 DMA.md",
|
||||||
|
|||||||
@@ -295,4 +295,203 @@ SetIntrMask(old_mask);
|
|||||||
|
|
||||||
4. **Сочетание с обработчиками**: Даже если прерывание разрешено маской, для него должен быть установлен обработчик через соответствующие функции PsyQ.
|
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 для удобства.
|
||||||
Reference in New Issue
Block a user