0c8acf75347362090303e7640e4231da07da1314
[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         pop ebx
44         pop ebp
45         ret
46
47 PIC1_CMD equ 20h
48 PIC1_DATA equ 21h
49 PIC2_CMD equ 0a0h
50 PIC2_DATA equ 0a1h
51
52 ; PIC initialization command word 1 bits
53 ICW1_ICW4_NEEDED        equ 01h
54 ICW1_SINGLE             equ 02h
55 ICW1_INTERVAL4          equ 04h
56 ICW1_LEVEL              equ 08h
57 ICW1_INIT               equ 10h
58 ; PIC initialization command word 4 bits
59 ICW4_8086               equ 01h
60 ICW4_AUTO_EOI           equ 02h
61 ICW4_BUF_SLAVE          equ 08h
62 ICW4_BUF_MASTER         equ 0ch
63 ICW4_SPECIAL            equ 10h
64 ; PIC operation command word 2 bits
65 OCW2_EOI                equ 20h
66
67 init_pic:
68         ; send ICW1 saying we'll follow with ICW4 later on
69         mov al, ICW1_INIT | ICW1_ICW4_NEEDED
70         out PIC1_CMD, al
71         out PIC2_CMD, al
72         ; send ICW2 with IRQ remapping
73         mov al, IRQ_OFFSET
74         out PIC1_DATA, al
75         add al, 8
76         out PIC2_DATA, al
77         ; send ICW3 to setup the master/slave relationship
78         ; ... set bit3 = 3rd interrupt input has a slave
79         mov al, 4
80         out PIC1_DATA, al
81         ; ... set slave ID to 2
82         mov al, 2
83         out PIC2_DATA, al
84         ; send ICW4 to set 8086 mode (no calls generated)
85         mov al, ICW4_8086
86         out PIC1_DATA, al
87         out PIC2_DATA, al
88         ; done, reset the data port to 0
89         xor al, al
90         out PIC1_DATA, al
91         out PIC2_DATA, al
92         ret