--- /dev/null
+ bits 32
+ section .text
+
+ extern intr_handler
+
+PIC1_CMD_PORT equ 0x20
+PIC2_CMD_PORT equ 0xa0
+OCW2_EOI equ 0x20
+OCW3_ISR equ 0x0b
+
+ global set_idt
+set_idt:
+ mov eax, [esp + 4]
+ mov [idtbase], eax
+ mov ax, [esp + 8]
+ mov [idtlim], ax
+ lidt [idtlim]
+ ret
+
+ align 4
+ dw 0
+idtlim dw 0
+idtbase dd 0
+
+
+ ; special entry point for IRQ7 to catch and disregard spurious interrupts
+ global intr_entry_irq7_verify
+intr_entry_irq7_verify:
+ push eax
+ mov al, OCW3_ISR
+ out PIC1_CMD_PORT, al
+ in al, PIC1_CMD_PORT
+ and al, 0x80
+ pop eax
+ jnz intr_entry_irq7
+ iret
+
+ global intr_entry_irq15_verify
+intr_entry_irq15_verify:
+ ; similarly for IRQ15
+ push eax
+ mov al, OCW3_ISR
+ out PIC2_CMD_PORT, al
+ in al, PIC2_CMD_PORT
+ and al, 0x80
+ jnz .valid
+ ; it was spurious, send EOI to master PIC and iret
+ mov al, OCW2_EOI
+ out PIC1_CMD_PORT, al
+ pop eax
+ iret
+.valid: pop eax
+ jmp intr_entry_irq15
+
+
+%macro intr_entry_err 2
+intr_entry_%2:
+ push dword %1 ; push interrupt number
+ jmp intr_entry_common
+%endmacro
+
+%macro intr_entry_noerr 2
+intr_entry_%2:
+ push dword 0 ; push dummy error code
+ push dword %1 ; push interrupt number
+ jmp intr_entry_common
+%endmacro
+
+intr_entry_common:
+ pusha ; save general purpose registers
+ call intr_handler
+ popa ; restore general purpose registers
+ add esp, 8 ; remove error code and intr number from the stack
+ iret
+
+ ; interrupt entry points
+ intr_entry_noerr 0, div
+ intr_entry_noerr 1, debug
+ intr_entry_noerr 2, nmi
+ intr_entry_noerr 3, bpt
+ intr_entry_noerr 4, ovf
+ intr_entry_noerr 5, bound
+ intr_entry_noerr 6, ill
+ intr_entry_noerr 7, nodev
+ intr_entry_err 8, dbl
+ intr_entry_noerr 9, copseg
+ intr_entry_err 10, tss
+ intr_entry_err 11, segpres
+ intr_entry_err 12, stack
+ intr_entry_err 13, prot
+ intr_entry_err 14, page
+ intr_entry_noerr 15, rsvd
+ intr_entry_noerr 16, fpu
+ intr_entry_err 17, align
+ intr_entry_noerr 18, mce
+ intr_entry_noerr 19, sse
+ ; remapped IRQs 0-15 -> 32-47
+ intr_entry_noerr 32, irq0
+ intr_entry_noerr 33, irq1
+ intr_entry_noerr 34, irq2
+ intr_entry_noerr 35, irq3
+ intr_entry_noerr 36, irq4
+ intr_entry_noerr 37, irq5
+ intr_entry_noerr 38, irq6
+ intr_entry_noerr 39, irq7
+ intr_entry_noerr 40, irq8
+ intr_entry_noerr 41, irq9
+ intr_entry_noerr 42, irq10
+ intr_entry_noerr 43, irq11
+ intr_entry_noerr 44, irq12
+ intr_entry_noerr 45, irq13
+ intr_entry_noerr 46, irq14
+ intr_entry_noerr 47, irq15
+ ; default handler
+ intr_entry_noerr 255, default
+
+; vi:ft=nasm: