есть следующий код: Код (Text): ; Allow IRQs interrupts, ; replace IRQs from (8h-0fh) to (30h-37h) ; (70h-77h) to (38h-3fh) in al,21h mov LowIRQMask,al mov bx,_SysInterruptMask mov al,0 or al,bl or al,3 ; Timer & Keyboard must be allowed out 21h,al in al,0a1h mov HighIRQMask,al mov al,0 or al,bh out 0a1h,al push 3830h call _SysSetIRQs add esp,4 и SysSetIRQs: Код (Text): ;---------------------------------------- ; Set new IRQ Addresses ; bl - low vector base (8 vects.) ; bh - high vector base (8 vects.) ;---------------------------------------- _SysSetIRQs proc near push ebp mov ebp,esp push ebx mov bx,word ptr [ebp + 8] mov al,11h out 20h,al jmp short $+2 mov al,bl out 21h,al jmp short $+2 mov al,4h out 21h,al jmp short $+2 mov al,1h out 21h,al jmp short $+2 mov al,11h out 0a0h,al jmp short $+2 mov al,bh out 0a1h,al jmp short $+2 mov al,2h out 0a1h,al jmp short $+2 mov al,1h out 0a1h,al pop ebx pop ebp ret endp с маской 0xffff или 0x0 результат один и тот же (работают не все прерывания что нужно), в чем ошибка?
В PIC, как мне кажется, прерывания маскируются единичным значением бита, а не наоборот. Кроме того, для нормальной работы каскада должен быть размаскировано второе (при нумерации с нуля) прерывание. Ну и самое главное, у тебя прерывания от локальных источников могут быть замаскированы или перенаправлены в APIC.
Кстати, генерация прерываний может быть отключена в самих контроллерах устройств, хотя не думаю, что причина именно в этом. Потом "все прерывания" будут работать, если они все задействованы устройствами. Ты уверен, что прерывания вообще должны происходить?
Может, в самом коде ошибка. Я например выполняю инициализацию немного по-другому. Код (Text): ; --------------------------------------------------------------------------- ; Перепрограммирование контроллера прерываний ; --------------------------------------------------------------------------- ; На входе: ; bl - индекс обработчика для IRQ0 (должен быть кратен восьми) ; bh - индекс обработчика для IRQ8 (должен быть кратен восьми) ; dx - битовая маска для IRQ0-IRQ15 (0 - разрешение, 1 - запрет) ; --------------------------------------------------------------------------- ; На выходе: нет ; --------------------------------------------------------------------------- ; Используемые регистры: al ; --------------------------------------------------------------------------- reset_pic: mov al, 00010001b out 20h, al out 0A0h, al mov al, bl out 21h, al mov al, bh out 0A1h, al mov al, 00000100b out 21h, al mov al, 02h out 0A1h, al mov al, [b]00001101b[/b] out 21h, al mov al, [b]00001001b[/b] out 0A1h, al mov al, dl out 21h, al mov al, dh out 0A1h, al ret
вырезка из книги Зубкова С. В. Код (Text): ; процедура init_pic ; выполняет инициализацию обоих контроллеров прерываний, ; отображая IRQ0 - IRQ7 на PIC1_BASE - PIC1_BASE+7, ; a IRQ8 - IRQ15 на PIC2_BASE - PIC2_BASE+7 ; для возврата в стандартное состояние вызвать с ; PIC1_BASE = 08h ; PIC2_BASE = 70h init_picproc near cli mov al,00010101b ; ICW1 out 20h,al out 0A0h,al mov al,PIC1_BASE ; ICW2 для первого контроллера out 2lh,al mov al,PIC2_BASE ; ICW2 для второго контроллера out 0A1h,al mov al,04h ; ICW.3 для первого контроллера out 21h,al mov al,02h ; ICW3 для второго контроллера out 0A1h,al mov al,00001101b ; ICW4 для первого контроллера out 21h,al mov al,00001001b ; ICW4 для второго контроллера out 0A1h,al sti ret init_pic endp У тебя должно быть У меня в подобной процедуре именно так
сделал как у вас работает все что нужно кроме 11-ого irq. Оно один раз (видно по диагностике) вызывается после разрешения командой sti и потом глухо почему-то.
а какое устройство у тебя на 11-м интеррапте? Иногда, в самом устройстве, которое сгенерило прерывание, прерывания запрещаются. Обработчик прерывания должен после обработки разрешить прерывания от этого устройства в самом устройстве через соответствующий регистр данного устройства (типа InterruptStatusRegister). Вобще с перываниями тут ветвистая архитектура. Если не ясно, после обеда могу попытаться прояснить.
ну а у тебя есть драйвер, обслуживающий этот изернет? Если нет, то все логично получается. Я вобще всегда москирую прерывания, в которых не нуждаюсь.
Barbos, мне Зубков не указ, тем более что у него есть опечатки. Предпочитаю использовать документацию по железу. Так что должно быть, как у меня
и, действительно, не ясно получается. Таблица прерываний в Protect Mode состоит из 8-байтных структур. А 2-й бит в посылке ICW1 определяет разрядность вектора. И вот у этого же Зубкова такая строка тогда, помню, наугад поставил единицу - заработало, ну и хорошо)). Конечно интересно будет поиграть с ним.
Зы Я сам когда-то писал про четвертое слово инициализации и приводил в качестве примера такой код. Код (Text): mov al, 00000001b out 21h, al out 0A1h, al Но там описывается вариативность установки второго и третьего битов. Источник: board.sysbin.com
Barbos Написанно. Для режима 8086/8088 ADI не влияет. Там передается номер прерывания и адресс прерывания(вернее номер который записан).