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
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.
17 + * I found a way to write it in C --EB 15 Jan 97
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.
26 + * I got frustrated with the old incomplete version. Especially
27 + * because of indent problems and I don't believe in changing code I
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
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. :)
41 + * Note Comments taken from the original C version
46 /* see assembly language version below */
49 /* find the highest priority unmasked requested irq and run it */
56 #warning using C run_irqs
57 + /* Old hack, to be removed */
58 + if (in_dpmi && in_dpmi_timer_int) return;
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.
69 - if(!(pic_irr&~(pic_isr|pic_imr))) return; /* exit if nothing to do */
71 - if(!(pic_irr&~(pic_isr))) return; /* exit if nothing to do */
73 - old_ilevel=pic_ilevel; /* save old pic_ilevl */
76 - while(int_request= pic_irr&~(pic_isr|pic_imr)) /* while something to do*/
78 - while(int_request= pic_irr&~(pic_isr)) /* while something to do*/
82 - pic_ilevel=find_bit(&int_request); /* find out what it is */
84 - if(pic_ilevel<(old_ilevel+pic_smm)) /* priority check */
85 - if(clear_bit(pic_ilevel,&pic_irr)) /* dbl check & clear req*/
87 - /* we got one! it is identified by pic_ilevel */
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 */
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.
106 + old_ilevel=pic_ilevel; /* save old pic_ilevl */
107 + priority = pic_smm + old_ilevel; /* check spec. mask mode */
109 + while((int_request = pic_irr & ~(pic_isr | pic_imr)) != 0) { /* while something to do*/
110 + int local_pic_ilevel;
112 + if (!isset_IF() && !in_dpmi)
113 + goto exit; /* exit if ints are disabled */
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)
120 + if (local_pic_ilevel > priority) /* priority check */
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 */
133 + /* whether we did or didn't :-( get one, we must still reset pic_ilevel */
134 + pic_ilevel=old_ilevel;
138 --- src/include/bitops.h Sun Mar 5 05:57:39 2000
139 +++ src/include/bitops.h Sun Oct 28 08:58:04 2001
141 #define _STATIC_ static
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);
150 #define ADDR (*(struct __dummy *) addr)
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 */
157 + * find_bit returns the bit number of the lowest bit that's set
158 + * Returns -1 if no one exists.
161 -find_bit(void *addr)
162 +find_bit(unsigned long int word)
166 - __asm__ __volatile__("bsfl %1,%0"
167 - :"=r" (bitno):"m"(ADDR));
169 + int result = -1; /* value to return on error */
170 + __asm__("bsfl %2,%0"
171 + :"=r" (result) /* output */
172 + :"0" (result), "r" (word)); /* input */
176 /* atomic increment flag and decrement flag operations */
178 atomic_inc(long *addr)