; 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
+ ; install trap handlers
+ set_trap 0, trap_entry_div
+ set_trap 1, trap_entry_debug
+ set_trap 2, trap_entry_nmi
+ set_trap 3, trap_entry_bp
+ set_trap 4, trap_entry_overflow
+ set_trap 5, trap_entry_bound
+ set_trap 6, trap_entry_ill
+ set_trap 7, trap_entry_nodev
+ set_trap 8, trap_entry_dfault
+ set_trap 9, trap_entry_copseg
+ set_trap 10, trap_entry_tss
+ set_trap 11, trap_entry_segpres
+ set_trap 12, trap_entry_stack
+ set_trap 13, trap_entry_prot
+ set_trap 14, trap_entry_page
+ set_trap 15, trap_entry_reserved
+ set_trap 16, trap_entry_fpu
+ set_trap 17, trap_entry_align
+ set_trap 18, trap_entry_mce
+ set_trap 19, trap_entry_sse
+
+ ; 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
ret
+%macro trap_err 2
+ global trap_entry_%2
+trap_entry_%2:
+ push dword %1
+ jmp trap_entry_common
+%endmacro
+
+%macro trap_noerr 2
+ global trap_entry_%2
+trap_entry_%2:
+ push dword 0
+ push dword %1
+ jmp trap_entry_common
+%endmacro
+
+trap_entry_common:
+ pusha
+ ; do exception handling
+ popa
+ add esp, 8 ; remove error code and exception number from stack
+ iret
+
+ trap_noerr 0, div
+ trap_noerr 1, debug
+ trap_noerr 2, nmi
+ trap_noerr 3, bp
+ trap_noerr 4, overflow
+ trap_noerr 5, bound
+ trap_noerr 6, ill
+ trap_noerr 7, nodev
+ trap_err 8, dfault
+ trap_noerr 9, copseg
+ trap_err 10, tss
+ trap_err 11, segpres
+ trap_err 12, stack
+ trap_err 13, prot
+ trap_err 14, page
+ trap_noerr 15, reserved
+ trap_noerr 16, fpu
+ trap_err 17, align
+ trap_noerr 18, mce
+ trap_noerr 19, sse
+
+
global set_intr
set_intr:
+ push ebp
+ mov ebp, esp
+ push ebx
+
+ mov ebx, [ebp + 8]
+ mov ax, GATE_TRAP
+ cmp ebx, 32 ; determine if it's an IRQ or an exception (trap)
+ jb .notirq
+ mov ax, GATE_INTR
+.notirq:
+ lea ebx, [ebx * 8 + idt] ; ebx <- pointer to gate descriptor
+ ; type|dpl goes to the 3rd word of the descriptor (dpl is 0)
+ or ax, (GATE_DEFAULT | GATE_PRESENT)
+ mov [ebx + 4], ax
+ ; address low 16bits go to the first word of the descriptor
+ mov eax, [ebp + 12]
+ mov [ebx], ax
+ ; address high 16bits go to the last word of the descriptor
+ shr eax, 16
+ mov [ebx + 6], ax
+ ; selector (kcode:1) goes to the second word of the descriptor
+ mov word [ebx + 2], 08h
+
+ pop ebx
+ pop ebp
ret
-PIC1_CMD equ 20h
-PIC1_DATA equ 21h
-PIC2_CMD equ 0a0h
-PIC2_DATA equ 0a1h
+dummy_intr_pic1:
+ pusha
+ end_of_irq 0
+ popa
+ iret
+
+dummy_intr_pic2:
+ pusha
+ end_of_irq 8
+ popa
+ iret
; PIC initialization command word 1 bits
ICW1_ICW4_NEEDED equ 01h
ICW4_BUF_SLAVE equ 08h
ICW4_BUF_MASTER equ 0ch
ICW4_SPECIAL equ 10h
-; PIC operation command word 2 bits
-OCW2_EOI equ 20h
init_pic:
; send ICW1 saying we'll follow with ICW4 later on