porting the demo to miniglut
[dosdemo] / libs / mikmod / drivers / dos / dosirq.h
1 /*
2     Interface for IRQ routines on DOS
3     Copyright (C) 1999 by Andrew Zabolotny, <bit@eltech.ru>
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public
16     License along with this library; if not, write to the Free
17     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #ifndef __DOSIRQ_H__
21 #define __DOSIRQ_H__
22
23 #include <pc.h>
24
25 #define PIC1_BASE       0x20            /* PIC1 base */
26 #define PIC2_BASE       0xA0            /* PIC2 base */
27
28 struct irq_handle {
29         void (*c_handler) ();           /* The real interrupt handler */
30         unsigned long handler_size;     /* The size of interrupt handler */
31         unsigned long handler;          /* Interrupt wrapper address */
32         unsigned long prev_selector;    /* Selector of previous handler */
33         unsigned long prev_offset;      /* Offset of previous handler */
34         unsigned char irq_num;          /* IRQ number */
35         unsigned char int_num;          /* Interrupt number */
36         unsigned char pic_base;         /* PIC base (0x20 or 0xA0) */
37         unsigned char pic_mask;         /* Old PIC mask state */
38 };
39
40 /* Return the enabled state for specific IRQ */
41 static inline unsigned char irq_state(struct irq_handle * irq)
42 {
43         return ((~inportb(irq->pic_base + 1)) & (0x01 << (irq->irq_num & 7)));
44 }
45
46 /* Acknowledge the end of interrupt */
47 static inline void _irq_ack(int irqno)
48 {
49         outportb(irqno > 7 ? PIC2_BASE : PIC1_BASE, 0x60 | (irqno & 7));
50         /* For second controller we also should acknowledge first controller */
51         if (irqno > 7)
52                 outportb(PIC1_BASE, 0x20);      /* 0x20, 0x62? */
53 }
54
55 /* Acknowledge the end of interrupt */
56 static inline void irq_ack(struct irq_handle * irq)
57 {
58         outportb(irq->pic_base, 0x60 | (irq->irq_num & 7));
59         /* For second controller we also should acknowledge first controller */
60         if (irq->pic_base != PIC1_BASE)
61                 outportb(PIC1_BASE, 0x20);      /* 0x20, 0x62? */
62 }
63
64 /* Mask (disable) the particular IRQ given his ordinal */
65 static inline void _irq_disable(int irqno)
66 {
67         unsigned int port_no = (irqno < 8 ? PIC1_BASE : PIC2_BASE) + 1;
68         outportb(port_no, inportb(port_no) | (1 << (irqno & 7)));
69 }
70
71 /* Unmask (enable) the particular IRQ given its ordinal */
72 static inline void _irq_enable(int irqno)
73 {
74         unsigned int port_no = (irqno < 8 ? PIC1_BASE : PIC2_BASE) + 1;
75         outportb(port_no, inportb(port_no) & ~(1 << (irqno & 7)));
76 }
77
78 /* Mask (disable) the particular IRQ given its irq_handle structure */
79 static inline void irq_disable(struct irq_handle * irq)
80 {
81         outportb(irq->pic_base + 1,
82                  inportb(irq->pic_base + 1) | (1 << (irq->irq_num & 7)));
83 }
84
85 /* Unmask (enable) the particular IRQ given its irq_handle structure */
86 static inline void irq_enable(struct irq_handle * irq)
87 {
88         outportb(irq->pic_base + 1,
89                  inportb(irq->pic_base + 1) & ~(1 << (irq->irq_num & 7)));
90 }
91
92 /* Check if a specific IRQ is pending: return 0 is no */
93 static inline int irq_check(struct irq_handle * irq)
94 {
95         outportb(irq->pic_base, 0x0B);  /* Read IRR vector */
96         return (inportb(irq->pic_base) & (1 << (irq->irq_num & 7)));
97 }
98
99 /* Hook a specific IRQ; NOTE: IRQ is disabled upon return, irq_enable() it */
100 extern struct irq_handle *irq_hook(int irqno, void (*handler)(),
101                                    unsigned long size);
102 /* Unhook a previously hooked IRQ */
103 extern void irq_unhook(struct irq_handle * irq);
104 /* Start IRQ detection process (IRQ list is given with irq mask) */
105 /* irq_confirm should return "1" if the IRQ really comes from the device */
106 extern void irq_detect_start(unsigned int irqs,
107                              int (*irq_confirm) (int irqno));
108 /* Finish IRQ detection process */
109 extern void irq_detect_end();
110 /* Get the count of specific irqno that happened */
111 extern int irq_detect_get(int irqno, unsigned int *irqmask);
112 /* Clear IRQ counters */
113 extern void irq_detect_clear();
114
115 /* The size of interrupt stack */
116 extern unsigned int __irq_stack_size;
117 /* The number of nested interrupts that can be handled */
118 extern unsigned int __irq_stack_count;
119
120 #endif /* __DOSIRQ_H__ */
121
122 /* ex:set ts=4: */