--- /dev/null
+#ifndef INTR_H_
+#define INTR_H_
+
+#include <inttypes.h>
+#include "asmutil.h"
+
+#define IRQ_TO_INUM(x) ((x) + 8)
+#define INUM_TO_IRQ(x) ((x) - 8)
+
+/* general purpose registers, pushed by interrupt entry routine */
+struct registers {
+ uint16_t di, si, bp, sp;
+ uint16_t bx, dx, cx, ax;
+} __attribute__((packed));
+
+struct intr_frame {
+ /* registers pushed by intr_entry_* */
+ struct registers regs;
+ /* interrupt number */
+ uint16_t inum;
+ /* pushed by CPU during interrupt entry */
+ uint16_t ip, cs, flags;
+} __attribute__((packed));
+
+typedef void (*intr_func_t)(struct intr_frame *frm);
+
+void init_intr(void);
+void dispatch_intr(struct intr_frame frm);
+
+/* set low level interrupt vector */
+void set_intr_vect(int n, uint16_t seg, uint16_t offs);
+/* set interrupt callback */
+void set_intr(int n, intr_func_t func);
+
+void mask_irq(int n);
+void unmask_irq(int n);
+
+#define end_of_irq(n) \
+ asm volatile( \
+ "\n\ttest $8, %0" \
+ "\n\tjz 0f" \
+ "\n\tmov $0x20, %%ax" \
+ "\n\tout %%ax, $0xa0" \
+ "\n0:\tmov $0x20, %%ax" \
+ "\n\tout %%ax, $0x20" \
+ :: "a"(n))
+
+#endif /* INTR_H_ */