/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * PIC (interrupt controller) handling routines. * * By Ove Kaaven. * * See readme.txt for copyright information. */ #include "allegro.h" #include "allegro/internal/aintern.h" #include "allegro/platform/aintdos.h" #ifndef ALLEGRO_DOS #error something is wrong with the makefile #endif static int pic_virgin = TRUE; static unsigned char default_pic1; static unsigned char default_pic2; static unsigned char altered_pic1; static unsigned char altered_pic2; /* exit_irq: * Restores the default hardware interrupt masks. */ static void exit_irq(void) { if (!pic_virgin) { outportb(0x21, default_pic1); outportb(0xA1, default_pic2); _remove_exit_func(exit_irq); pic_virgin = TRUE; } } /* init_irq: * Reads the default hardware interrupt masks. */ static void init_irq(void) { if (pic_virgin) { default_pic1 = inportb(0x21); default_pic2 = inportb(0xA1); altered_pic1 = 0; altered_pic2 = 0; _add_exit_func(exit_irq, "exit_irq"); pic_virgin = FALSE; } } /* _restore_irq: * Restores default masking for a hardware interrupt. */ void _restore_irq(int num) { unsigned char pic; if (!pic_virgin) { if (num>7) { pic = inportb(0xA1) & (~(1<<(num-8))); outportb(0xA1, pic | (default_pic2 & (1<<(num-8)))); altered_pic2 &= ~(1<<(num-8)); if (altered_pic2) return; num = 2; /* if no high IRQs remain, also restore Cascade (IRQ2) */ } pic = inportb(0x21) & (~(1< 7) { outportb(0x21, pic & 0xFB); /* unmask Cascade (IRQ2) interrupt */ pic = inportb(0xA1); outportb(0xA1, pic & (~(1<<(num-8)))); /* unmask PIC-2 interrupt */ altered_pic2 |= 1<<(num-8); } else { outportb(0x21, pic & (~(1< 7) { pic = inportb(0xA1); outportb(0xA1, pic & (1<<(num-8))); /* mask PIC-2 interrupt */ altered_pic2 |= 1<<(num-8); } else { pic = inportb(0x21); outportb(0x21, pic & (1<