fixed the interrupt gate descriptor setup
[ld45_start_nothing] / src / intr.asm
index 1bbf319..fdd06ef 100644 (file)
 ; 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
@@ -29,8 +140,6 @@ ICW4_AUTO_EOI                equ 02h
 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