foo
[ld45_start_nothing] / src / intr.asm
1 ; vi:filetype=nasm ts=8 sts=8 sw=8:
2         section .text
3
4 %define INTR_ASM_
5 %include "intr.inc"
6
7 GATE_INTR equ 0600h
8 GATE_TRAP equ 0700h
9 GATE_DEFAULT equ 0800h
10 GATE_PRESENT equ 8000h
11
12         global init_intr
13 init_intr:
14         call init_pic
15         ret
16
17         global set_intr
18 set_intr:
19         push ebp
20         mov ebp, esp
21         push ebx
22
23         mov ebx, [ebp + 8]
24         mov eax, GATE_TRAP
25         cmp ebx, 32     ; determine if it's an IRQ or an exception (trap)
26         jb .notirq
27         mov eax, GATE_INTR
28 .notirq:
29         shl ebx, 1
30         lea ebx, [ebx * 8 + idt] ; ebx <- pointer to gate descriptor
31         ; type|dpl goes to the 3rd dword of the descriptor (dpl is 0)
32         or eax, (GATE_DEFAULT | GATE_PRESENT)
33         mov [ebx + 8], eax
34         ; address low 16bits go to the first dword of the descriptor
35         mov eax, [ebp + 12]
36         mov [ebx], ax
37         ; address high 16bits go to the last dword of the descriptor
38         shr eax, 16
39         mov [ebx + 12], eax
40         ; selector (kcode:1) goes to the second dword of the descriptor
41         mov dword [ebx + 4], 08h
42
43         ; install dummy interrupt handlers for all IRQ vectors
44 %assign i 0
45 %rep 8
46         set_irq_vector i, dummy_intr_pic1
47         set_irq_vector i+8, dummy_intr_pic2
48 %assign i i+1
49 %endrep
50
51         pop ebx
52         pop ebp
53         ret
54
55 dummy_intr_pic1:
56         push eax
57         end_of_irq 0
58         pop eax
59         iret
60
61 dummy_intr_pic2:
62         push eax
63         end_of_irq 8
64         pop eax
65         iret
66
67 ; PIC initialization command word 1 bits
68 ICW1_ICW4_NEEDED        equ 01h
69 ICW1_SINGLE             equ 02h
70 ICW1_INTERVAL4          equ 04h
71 ICW1_LEVEL              equ 08h
72 ICW1_INIT               equ 10h
73 ; PIC initialization command word 4 bits
74 ICW4_8086               equ 01h
75 ICW4_AUTO_EOI           equ 02h
76 ICW4_BUF_SLAVE          equ 08h
77 ICW4_BUF_MASTER         equ 0ch
78 ICW4_SPECIAL            equ 10h
79
80 init_pic:
81         ; send ICW1 saying we'll follow with ICW4 later on
82         mov al, ICW1_INIT | ICW1_ICW4_NEEDED
83         out PIC1_CMD, al
84         out PIC2_CMD, al
85         ; send ICW2 with IRQ remapping
86         mov al, IRQ_OFFSET
87         out PIC1_DATA, al
88         add al, 8
89         out PIC2_DATA, al
90         ; send ICW3 to setup the master/slave relationship
91         ; ... set bit3 = 3rd interrupt input has a slave
92         mov al, 4
93         out PIC1_DATA, al
94         ; ... set slave ID to 2
95         mov al, 2
96         out PIC2_DATA, al
97         ; send ICW4 to set 8086 mode (no calls generated)
98         mov al, ICW4_8086
99         out PIC1_DATA, al
100         out PIC2_DATA, al
101         ; done, reset the data port to 0
102         xor al, al
103         out PIC1_DATA, al
104         out PIC2_DATA, al
105         ret