Лисья Нора

Оглавление


§ Объяснение

Очень часто, когда переводится программа в защищенный режим, возникает проблема с IRQ, которые по старинке, находятся по адресам 08-0F для Master и 70-77 для Slave, что совершенно неприемлемо, потому что на векторах 00-1F зарезервированы системные исключения, которые надо тоже как-то обрабатывать. Из-за этого, надо сделать код, который перенаправляет на новые вектора 20-2F. Этот код ниже.

§ Вектора системных исключений

; Offset | INT # | Description
; -----------+-----------+-----------------------------------
; $0000 | 0x00 | Divide by 0
; $0004 | 0x01 | Trace
; $0008 | 0x02 | NMI Interrupt
; $000C | 0x03 | Breakpoint (INT3)
; $0010 | 0x04 | Overflow (INTO)
; $0014 | 0x05 | Bounds range exceeded (BOUND)
; $0018 | 0x06 | Invalid opcode (UD2)
; $001C | 0x07 | Device not available (WAIT/FWAIT)
; -----------------------------------------------------------
; $0020 | 0x08 | Double fault
; $0024 | 0x09 | Coprocessor segment overrun
; $0028 | 0x0A | Invalid TSS
; $002C | 0x0B | Segment not present
; $0030 | 0x0C | Stack-segment fault
; $0034 | 0x0D | General protection fault
; $0038 | 0x0E | Page fault
; $003C | 0x0F | ---
; $0040 | 0x10 | x87 FPU error
; $0044 | 0x11 | Alignment check
; $0048 | 0x12 | Machine check
; $004C | 0x13 | SIMD Floating-Point Exception
; $00xx | 0x14-0x1F | ---
; -----------------------------------------------------------

§ Код для ассемблера

На всякий случай, если включен APIC – более расширенная версия PIC, нужно его отключить в целях совместимости со старым железом, таким как 386 и ниже.
push ax
mov ecx, 1Bh
rdmsr
and eax, 0xFFFFF7FF
wrmsr
Помимо редиректа, на вход подается AX, 16 бит которые обозначают, разрешены ли прерывания IRQ или нет. Например если установлен бит 0, то разрешен IRQ#0 (Timer).
mov al, 0x10 + 0x01 ; ICW1_INIT + ICW1_ICW4
out 0x20, al ; PIC1_COMMAND
out 0xA0, al ; PIC2_COMMAND
mov al, 0x20
out 0x21 , al ; Master 20h-27h (PIC1_DATA)
mov al, 0x28
out 0xA1, al ; Slave 28h-2Fh (PIC2_DATA)
mov al, 4
out 0x21, al ; PIC1_DATA
mov al, 2
out 0xA1, al ; PIC2_DATA
mov al, 0x01 ; ICW4_8086
out 0x21, al ; PIC1_DATA
out 0xA1, al ; PIC2_DATA
pop bx
not bx
mov al, bl
out 0x21, al ; Bitmask LOW (PIC1_DATA)
mov al, bh
out 0xA1, al ; Bitmask HIGH (PIC2_DATA)
ret