extern intr_handler
PIC1_CMD_PORT equ 0x20
+PIC1_DATA_PORT equ 0x21
PIC2_CMD_PORT equ 0xa0
+PIC2_DATA_PORT equ 0xa1
+
+ICW1_ICW4_NEEDED equ 0x01
+ICW1_INIT equ 0x10
+ICW4_8086 equ 0x01
+
OCW2_EOI equ 0x20
OCW3_ISR equ 0x0b
idtbase dd 0
+ global prog_pic
+prog_pic:
+ ; send ICW1 saying we'll follow with ICW4 later
+ mov al, ICW1_INIT | ICW1_ICW4_NEEDED
+ out PIC1_CMD_PORT, al
+ ; send ICW2 with IRQ remapping
+ mov al, [esp + 4]
+ out PIC1_DATA_PORT, al
+ add al, 8
+ out PIC2_DATA_PORT, al
+ ; send ICW3 to setup the master/slave relationship
+ ; ... set bit3 = 3rd interrupt input has a slave
+ mov al, 4
+ out PIC1_DATA_PORT, al
+ ; ... set slave id to 2
+ mov al, 2
+ OUT PIC2_DATA_PORT, al
+ ; send ICW4 to set 8086 mode (no calls generated)
+ mov al, ICW4_8086
+ out PIC1_DATA_PORT, al
+ out PIC2_DATA_PORT, al
+ ; done, reset the data port to 0
+ xor al, al
+ out PIC1_DATA_PORT, al
+ out PIC2_DATA_PORT, al
+ ret
+
+
+ global end_of_irq
+end_of_irq:
+ mov eax, [esp + 4]
+ cmp eax, 8
+ jb .eoi_master
+ ; cascaded IRQ, send EOI to slave PIC first
+ mov al, OCW2_EOI
+ out PIC2_CMD_PORT, al
+.eoi_master: ; send EOI to master PIC
+ mov al, OCW2_EOI
+ out PIC1_CMD_PORT, al
+ ret
+
+
; special entry point for IRQ7 to catch and disregard spurious interrupts
global intr_entry_irq7_verify
intr_entry_irq7_verify:
%macro intr_entry_err 2
+ global intr_entry_%2
intr_entry_%2:
push dword %1 ; push interrupt number
jmp intr_entry_common
%endmacro
%macro intr_entry_noerr 2
+ global intr_entry_%2
intr_entry_%2:
push dword 0 ; push dummy error code
push dword %1 ; push interrupt number
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