added an old version of mikmod for dos
[dosdemo] / libs / oldmik / src / mirq.c
1 /*\r
2 \r
3 Name:\r
4 MDMA.C\r
5 \r
6 Description:\r
7 Some general purpose IRQ routines\r
8 \r
9 Portability:\r
10 \r
11 MSDOS:  BC(y)   Watcom(y)       DJGPP(y)\r
12 Win95:  n\r
13 Os2:    n\r
14 Linux:  n\r
15 \r
16 (y) - yes\r
17 (n) - no (not possible or not useful)\r
18 (?) - may be possible, but not tested\r
19 \r
20 */\r
21 #include <dos.h>\r
22 #include <conio.h>\r
23 #include "mirq.h"\r
24 \r
25 #define OCR1    0x20                    /* 8259-1 Operation control register */\r
26 #define IMR1    0x21                    /* 8259-1 Mask register */\r
27 \r
28 #define OCR2    0xA0                    /* 8259-2 Operation control register */\r
29 #define IMR2    0xA1                    /* 8259-2 Mask register */\r
30 \r
31 \r
32 BOOL MIrq_IsEnabled(UBYTE irqno)\r
33 /*\r
34         Returns true if the specified hardware irq is enabled.\r
35 */\r
36 {\r
37         UBYTE imr=(irqno>7) ? IMR2 : IMR1;              /* interrupt mask register */\r
38         UBYTE msk=1<<(irqno&7);                                 /* interrupt mask */\r
39         return((inportb(imr) & msk) == 0);\r
40 }\r
41 \r
42 \r
43 BOOL MIrq_OnOff(UBYTE irqno,UBYTE onoff)\r
44 /*\r
45         Use to enable or disable the specified irq.\r
46 */\r
47 {\r
48         UBYTE imr=(irqno>7) ? IMR2 : IMR1;              /* interrupt mask register */\r
49         UBYTE ocr=(irqno>7) ? OCR2 : OCR1;              /* ocr */\r
50         UBYTE msk=1<<(irqno&7);                                 /* interrupt mask */\r
51         UBYTE eoi=0x60|(irqno&7);                               /* specific end-of-interrupt */\r
52         BOOL oldstate;\r
53 \r
54         /* save current setting of this irq */\r
55         oldstate=((inportb(imr) & msk) == 0);\r
56 \r
57         if(onoff){\r
58                 outportb(imr,inportb(imr) & ~msk);\r
59                 outportb(ocr,eoi);\r
60                 if(irqno>7) MIrq_OnOff(2,1);\r
61         }\r
62         else{\r
63                 outportb(imr,inportb(imr) | msk);\r
64         }\r
65 \r
66         return oldstate;\r
67 }\r
68 \r
69 \r
70 void MIrq_EOI(UBYTE irqno)\r
71 /*\r
72         Clears the specified interrupt request at the interrupt controller.\r
73 */\r
74 {\r
75         outportb(0x20,0x20);\r
76         if(irqno>7) outportb(0xa0,0x20);\r
77 }\r
78 \r
79 \r
80 PVI MIrq_SetHandler(UBYTE irqno,PVI handler)\r
81 {\r
82 #ifdef __DJGPP__\r
83         _go32_dpmi_seginfo seginfo;\r
84 #endif\r
85         PVI oldvect;\r
86         int vecno=(irqno>7) ? irqno+0x68 : irqno+0x8;\r
87 #ifdef __DJGPP__\r
88         _go32_dpmi_get_protected_mode_interrupt_vector(vecno, &seginfo);\r
89         oldvect = seginfo.pm_offset;\r
90         seginfo.pm_offset = handler;\r
91         seginfo.pm_selector = _go32_my_cs();\r
92         _go32_dpmi_allocate_iret_wrapper(&seginfo);\r
93         _go32_dpmi_set_protected_mode_interrupt_vector(vecno, &seginfo);\r
94 #else\r
95         oldvect=_dos_getvect(vecno);\r
96         _dos_setvect(vecno,handler);\r
97 #endif\r
98         return oldvect;\r
99 }\r