Инструменты пользователя

Инструменты сайта


interrupt

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
interrupt [2026/10/15 20:30] – создано geckointerrupt [2026/10/25 17:06] (текущий) – gecko
Строка 9: Строка 9:
   * SR (cop0r12) - статусный регистр; позволяет произвольно включать и выключать обработку прерываний, а также маскировать те или иные линии.   * SR (cop0r12) - статусный регистр; позволяет произвольно включать и выключать обработку прерываний, а также маскировать те или иные линии.
  
-  * Cause (cop0r13) - регистр причины прерывания. Предоставляет битовые флаги линий прерываний и код, идентифицирующий тип последнего прерывания. Регистр имеет 8 линий: 2 для исключений (биты 8–9) и 6 для аппаратных прерываний (биты 10-15). PlayStation использует только одну линию аппаратных прерываний (бит 10), все остальные всегда нулевые.+  * Cause (cop0r13) - регистр причины прерывания. Предоставляет битовые флаги линий прерываний и код, идентифицирующий тип последнего прерывания. Регистр имеет 8 линий: 2 для исключений (биты 8-9) и 6 для аппаратных прерываний (биты 10-15). PlayStation использует только одну линию аппаратных прерываний (бит 10), все остальные всегда нулевые.
  
   * EPC (cop0r14) - содержит адрес инструкции, которая вызвала исключение. Если произошло аппаратное прерывание, то EPC содержит адрес следующей инструкции, которая должна выполниться после обработки.   * EPC (cop0r14) - содержит адрес инструкции, которая вызвала исключение. Если произошло аппаратное прерывание, то EPC содержит адрес следующей инструкции, которая должна выполниться после обработки.
Строка 24: Строка 24:
 Перед загрузкой игры BIOS отключает обработку прерываний, поэтому, чтобы работать с периферийными устройствами (геймпад, CD-ROM и пр.), нужно либо вручную установить биты 2 и 10 статусного регистра COP0, либо проинициализировать геймпад функцией BIOS InitPad. Перед загрузкой игры BIOS отключает обработку прерываний, поэтому, чтобы работать с периферийными устройствами (геймпад, CD-ROM и пр.), нужно либо вручную установить биты 2 и 10 статусного регистра COP0, либо проинициализировать геймпад функцией BIOS InitPad.
  
-Функции BIOS, относящиеся к обработке прерываний:+BIOS создает четыре очереди обработчиков прерываний: 
 + 
 +  * 0 - Системные исключения - syscall, деление на ноль, переполнение памяти; 
 +  * 1 - Прерывания от системных таймеров и [[VBlank]]; 
 +  * 2 - Зарезервировано; 
 +  * 3 - Обработчики аппаратных прерываний периферии. 
 + 
 +Перед вызовом очереди BIOS сохраняет все регистры общего назначения (GPR) в специальный буфер, так что самостоятельно это делать не нужно. 
 + 
 +===== Установка пользовательских обработчиков ===== 
 + 
 +Обработчики прерываний добавляются функцией BIOS SysEnqIntRP и убираются функцией SysDeqIntRP. Обе функции принимают вторым аргументом указатель на следующую структуру: 
 + 
 +<code c> 
 +struct IntRP 
 +{ 
 +    struct IntRP* next; // следующий элемент IntRP в связном списке, либо null, если это последний элемент 
 +    void* func2; // указатель на функцию, которая вызывается второй, если func1 вернула ненулевое значение 
 +    void* func1; // указатель на функцию, которая вызывается первой 
 +    int flag; // зарезервированное значение, должно быть равно нулю 
 +}; 
 +</code> 
 + 
 +Обработчик вызывается следующим образом: 
 +  * func2(func1()), если присутствуют обе функции; 
 +  * func1(), если присутствует первая функция, но отсутствует вторая; 
 +  * В иных случаях ничего не вызывается. 
 + 
 +Чтобы безопасно поместить элемент в очередь, необходимо обернуть этот вызов в критическую секцию, временно отключив аппаратные прерывания. Это предотвратит сбой в работе консоли, который мог бы произойти, если бы во время изменения указателей очереди возникло другое прерывание. 
 + 
 +BIOS по цепочке вызывает все зарегистрированные обработчики прерываний. Каждый обработчик должен проверить нужный бит регистра I_STAT и подтвердить его, записав в него ноль. Например: 
 + 
 +<code c> 
 +int irqVBlank() 
 +{ 
 +    if ((*I_STAT & IRQ0) && (*I_MASK & IRQ0)) 
 +    { 
 +        // Reset VBlank bit 
 +        *I_STAT = ~IRQ0; 
 +    } 
 +    return 0; 
 +} 
 +</code> 
 + 
 +Поскольку такой подход может привести к конфликтам, не рекомендуется навешивать на одну и ту же линию прерываний более одного обработчика. 
 + 
 +===== Функции BIOS, относящиеся к обработке прерываний ===== 
 + 
 +  * С(02h) - SysEnqIntRP(priorityIndex, handler) - добавляет обработчик прерывания в очередь. 
 + 
 +  * С(03h) - SysDeqIntRP(priorityIndex, handler) - убирает обработчик прерывания из очереди. 
 + 
 +  * B(18h) - ResetEntryInt() - удаляет все пользовательские обработчики.
  
   * int EnterCriticalSection(), вызов через syscall с номером 0x01 в регистре $a0 - отключает обработку прерываний, зануляя биты 2 и 10 регистра SR (cop0r12). Возвращает 1, если оба бита были установлены, и 0 в противном случае. Эту функцию нужно вызывать в редких случаях, когда нужно выполнить код, который не должен прерываться.   * int EnterCriticalSection(), вызов через syscall с номером 0x01 в регистре $a0 - отключает обработку прерываний, зануляя биты 2 и 10 регистра SR (cop0r12). Возвращает 1, если оба бита были установлены, и 0 в противном случае. Эту функцию нужно вызывать в редких случаях, когда нужно выполнить код, который не должен прерываться.
interrupt.1792096200.txt.gz · Последнее изменение: — gecko

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki