; vi:filetype=nasm ts=8 sts=8 sw=8: section .text %define INTR_ASM_ %include "intr.inc" GATE_INTR equ 0600h GATE_TRAP equ 0700h GATE_DEFAULT equ 0800h GATE_PRESENT equ 8000h global init_intr init_intr: call init_pic ret global set_intr set_intr: push ebp mov ebp, esp push ebx mov ebx, [ebp + 8] mov eax, GATE_TRAP cmp ebx, 32 ; determine if it's an IRQ or an exception (trap) jb .notirq mov eax, GATE_INTR .notirq: shl ebx, 1 lea ebx, [ebx * 8 + idt] ; ebx <- pointer to gate descriptor ; type|dpl goes to the 3rd dword of the descriptor (dpl is 0) or eax, (GATE_DEFAULT | GATE_PRESENT) mov [ebx + 8], eax ; address low 16bits go to the first dword of the descriptor mov eax, [ebp + 12] mov [ebx], ax ; address high 16bits go to the last dword of the descriptor shr eax, 16 mov [ebx + 12], eax ; selector (kcode:1) goes to the second dword of the descriptor mov dword [ebx + 4], 08h ; install dummy interrupt handlers for all IRQ vectors %assign i 0 %rep 8 set_irq_vector i, dummy_intr_pic1 set_irq_vector i+8, dummy_intr_pic2 %assign i i+1 %endrep pop ebx pop ebp ret dummy_intr_pic1: push eax end_of_irq 0 pop eax iret dummy_intr_pic2: push eax end_of_irq 8 pop eax iret ; PIC initialization command word 1 bits ICW1_ICW4_NEEDED equ 01h ICW1_SINGLE equ 02h ICW1_INTERVAL4 equ 04h ICW1_LEVEL equ 08h ICW1_INIT equ 10h ; PIC initialization command word 4 bits ICW4_8086 equ 01h ICW4_AUTO_EOI equ 02h ICW4_BUF_SLAVE equ 08h ICW4_BUF_MASTER equ 0ch ICW4_SPECIAL equ 10h init_pic: ; send ICW1 saying we'll follow with ICW4 later on mov al, ICW1_INIT | ICW1_ICW4_NEEDED out PIC1_CMD, al out PIC2_CMD, al ; send ICW2 with IRQ remapping mov al, IRQ_OFFSET out PIC1_DATA, al add al, 8 out PIC2_DATA, al ; send ICW3 to setup the master/slave relationship ; ... set bit3 = 3rd interrupt input has a slave mov al, 4 out PIC1_DATA, al ; ... set slave ID to 2 mov al, 2 out PIC2_DATA, al ; send ICW4 to set 8086 mode (no calls generated) mov al, ICW4_8086 out PIC1_DATA, al out PIC2_DATA, al ; done, reset the data port to 0 xor al, al out PIC1_DATA, al out PIC2_DATA, al ret