]>
Commit | Line | Data |
---|---|---|
e651c761 | 1 | diff -uNrX dosemu-ignore-files dosemu-1.1.1.3.eb1.1/src/base/dev/pic/pic.c |
2 | dosemu-1.1.1.3.eb1.1.1/src/base/dev/pic/pic.c | |
3 | --- src/base/dev/pic/pic.c Sat Oct 27 16:58:43 2001 | |
4 | +++ src/base/dev/pic/pic.c Sun Oct 28 08:57:08 2001 | |
5 | @@ -134,7 +134,6 @@ | |
6 | #ifndef C_RUN_IRQS | |
7 | #define C_RUN_IRQS | |
8 | #include "bitops.h" | |
9 | -#undef C_RUN_IRQS | |
10 | #else | |
11 | #include "bitops.h" | |
12 | #endif | |
13 | @@ -632,55 +631,83 @@ | |
14 | * assembly macros, because such macros can only return a single result. | |
15 | * If I find a way to do it in c, I will, but don't hold your breath. | |
16 | * | |
17 | + * I found a way to write it in C --EB 15 Jan 97 | |
18 | + * | |
19 | * DANG_END_FUNCTION | |
20 | */ | |
21 | #ifdef C_RUN_IRQS | |
22 | +/* DANG_BEGIN_COMMENT | |
23 | + * This is my C version of the assembly version of run_irqs. | |
24 | + * I believe it is a correct translation of the assembly into C. | |
25 | + * | |
26 | + * I got frustrated with the old incomplete version. Especially | |
27 | + * because of indent problems and I don't believe in changing code I | |
28 | + * don't understand. | |
29 | + * | |
30 | + * This code is correct in the single process case. | |
31 | + * Except possilby it's handling of special mask mode. | |
32 | + * If pic_smm is set to 32 it appears to me that no interrupt is | |
33 | + * ever run. | |
34 | + * | |
35 | + * But this code is certainly incorrect in the multiple process | |
36 | + * case. Because it spins without rereading pic_irr, to recalculate | |
37 | + * pic_ilevel. And I think there are other less serious problems as | |
38 | + * well. However it doesn't matter because we aren't doing multiple | |
39 | + * processes, or multiple threads. :) | |
40 | + * | |
41 | + * Note Comments taken from the original C version | |
42 | + * | |
43 | + * --EB 5 Jan 97 | |
44 | + * DANG_END_COMMENT | |
45 | + */ | |
46 | /* see assembly language version below */ | |
47 | -void run_irqs() | |
48 | +void run_irqs(void) | |
49 | /* find the highest priority unmasked requested irq and run it */ | |
50 | { | |
51 | - int old_ilevel; | |
52 | - int int_request; | |
53 | + int old_ilevel; | |
54 | + int int_request; | |
55 | + int priority; | |
56 | #warning using C run_irqs | |
57 | + /* Old hack, to be removed */ | |
58 | + if (in_dpmi && in_dpmi_timer_int) return; | |
59 | ||
60 | -/* check for and find any requested irqs. Having found one, we atomic-ly | |
61 | - * clear it and verify it was there when we cleared it. If it wasn't, we | |
62 | - * look for the next request. There are two in_service bits for pic1 irqs. | |
63 | - * This is needed, because irq 8-15 must do 2 outb20s, which, if the dos | |
64 | - * irq code actually runs, will reset the bits. We also reset them here, | |
65 | - * since dos code won't necessarily run. | |
66 | - */ | |
67 | - | |
68 | -#if 0 | |
69 | - if(!(pic_irr&~(pic_isr|pic_imr))) return; /* exit if nothing to do */ | |
70 | -#else | |
71 | - if(!(pic_irr&~(pic_isr))) return; /* exit if nothing to do */ | |
72 | -#endif | |
73 | - old_ilevel=pic_ilevel; /* save old pic_ilevl */ | |
74 | - | |
75 | -#if 0 | |
76 | - while(int_request= pic_irr&~(pic_isr|pic_imr)) /* while something to do*/ | |
77 | -#else | |
78 | - while(int_request= pic_irr&~(pic_isr)) /* while something to do*/ | |
79 | -#endif | |
80 | - { | |
81 | - | |
82 | - pic_ilevel=find_bit(&int_request); /* find out what it is */ | |
83 | - | |
84 | - if(pic_ilevel<(old_ilevel+pic_smm)) /* priority check */ | |
85 | - if(clear_bit(pic_ilevel,&pic_irr)) /* dbl check & clear req*/ | |
86 | - { | |
87 | - /* we got one! it is identified by pic_ilevel */ | |
88 | - | |
89 | - set_bit(pic_ilevel,&pic_isr); /* set in-service bit */ | |
90 | - pic1_isr = pic_isr & pic1_mask; /* pic1 too */ | |
91 | - pic_iinfo[pic_ilevel].func(); /* run the function */ | |
92 | - clear_bit(pic_ilevel,&pic_isr); /* clear in_service bit */ | |
93 | - clear_bit(pic_ilevel,&pic1_isr); /* pic1 too */ | |
94 | - } | |
95 | - } | |
96 | - /* whether we did or didn't :-( get one, we must still reset pic_ilevel */ | |
97 | - pic_ilevel=old_ilevel; | |
98 | + /* check for and find any requested irqs. Having found one, we atomic-ly | |
99 | + * clear it and verify it was there when we cleared it. If it wasn't, we | |
100 | + * look for the next request. There are two in_service bits for pic1 irqs. | |
101 | + * This is needed, because irq 8-15 must do 2 outb20s, which, if the dos | |
102 | + * irq code actually runs, will reset the bits. We also reset them here, | |
103 | + * since dos code won't necessarily run. | |
104 | + */ | |
105 | + | |
106 | + old_ilevel=pic_ilevel; /* save old pic_ilevl */ | |
107 | + priority = pic_smm + old_ilevel; /* check spec. mask mode */ | |
108 | + | |
109 | + while((int_request = pic_irr & ~(pic_isr | pic_imr)) != 0) { /* while something to do*/ | |
110 | + int local_pic_ilevel; | |
111 | + | |
112 | + if (!isset_IF() && !in_dpmi) | |
113 | + goto exit; /* exit if ints are disabled */ | |
114 | + | |
115 | + do { | |
116 | + local_pic_ilevel = find_bit(int_request); /* find out what it is */ | |
117 | + /* In case int_request has no bits set */ | |
118 | + if (local_pic_ilevel == -1) | |
119 | + goto exit; | |
120 | + if (local_pic_ilevel > priority) /* priority check */ | |
121 | + goto exit; | |
122 | + } while (clear_bit(local_pic_ilevel, &pic_irr) == 0); /* dbl check & clear req */ | |
123 | + pic_ilevel = local_pic_ilevel; | |
124 | + set_bit(local_pic_ilevel, &pic_isr); /* set in-service bit */ | |
125 | + set_bit(local_pic_ilevel, &pic1_isr); /* pic1 too */ | |
126 | + pic1_isr &= pic_isr & pic1_mask; /* isolate pic1 irqs */ | |
127 | + pic_iinfo[local_pic_ilevel].func(); /* run the function */ | |
128 | + local_pic_ilevel = pic_ilevel; | |
129 | + clear_bit(local_pic_ilevel, &pic_isr); /* clear in_service bit */ | |
130 | + clear_bit(local_pic_ilevel, &pic1_isr); /* pic1 too */ | |
131 | + } | |
132 | + exit: | |
133 | + /* whether we did or didn't :-( get one, we must still reset pic_ilevel */ | |
134 | + pic_ilevel=old_ilevel; | |
135 | } | |
136 | ||
137 | #else | |
138 | --- src/include/bitops.h Sun Mar 5 05:57:39 2000 | |
139 | +++ src/include/bitops.h Sun Oct 28 08:58:04 2001 | |
140 | @@ -35,7 +35,7 @@ | |
141 | #define _STATIC_ static | |
142 | #endif | |
143 | ||
144 | -_STATIC_ int find_bit(void * addr); | |
145 | +_STATIC_ int find_bit(unsigned long int word); | |
146 | _STATIC_ long atomic_inc(long * addr); | |
147 | _STATIC_ long atomic_dec(long * addr); | |
148 | _STATIC_ int set_bit(int nr, void * addr); | |
149 | @@ -60,18 +60,20 @@ | |
150 | #define ADDR (*(struct __dummy *) addr) | |
151 | ||
152 | /* JLS's stuff */ | |
153 | -/* find_bit returns the bit number of the lowest bit that's set */ | |
154 | -/* it doesn't need to be atomic, but it's much faster than using c */ | |
155 | - | |
156 | +/* | |
157 | + * find_bit returns the bit number of the lowest bit that's set | |
158 | + * Returns -1 if no one exists. | |
159 | + */ | |
160 | _INLINE_ int | |
161 | -find_bit(void *addr) | |
162 | +find_bit(unsigned long int word) | |
163 | { | |
164 | - int bitno; | |
165 | - | |
166 | - __asm__ __volatile__("bsfl %1,%0" | |
167 | - :"=r" (bitno):"m"(ADDR)); | |
168 | - return bitno; | |
169 | + int result = -1; /* value to return on error */ | |
170 | + __asm__("bsfl %2,%0" | |
171 | + :"=r" (result) /* output */ | |
172 | + :"0" (result), "r" (word)); /* input */ | |
173 | + return result; | |
174 | } | |
175 | + | |
176 | /* atomic increment flag and decrement flag operations */ | |
177 | _INLINE_ long int | |
178 | atomic_inc(long *addr) |