1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
/*
* PC/HW routine collection v1.3 for DOS/DJGPP
*
* Copyright (C) 2002 - Daniel Borca
* Email : dborca@yahoo.com
* Web : http://www.geocities.com/dborca
*/
.file "pc_irq.S"
.text
#define IRQ_STACK_SIZE 16384
#define IRQ_WRAPPER_LEN (__irq_wrapper_1-__irq_wrapper_0)
#define IRQ_OLD (__irq_old_0-__irq_wrapper_0)
#define IRQ_HOOK (__irq_hook_0-__irq_wrapper_0)
#define IRQ_STACK (__irq_stack_0-__irq_wrapper_0)
.balign 4
common:
movw $0x0400, %ax
int $0x31
movl %ss:8(%ebp), %ebx
cmpl $15, %ebx
jbe 0f
fail:
orl $-1, %eax
popl %edi
popl %ebx
leave
ret
0:
movl %ebx, %edi
imull $IRQ_WRAPPER_LEN, %edi
addl $__irq_wrapper_0, %edi
cmpb $7, %bl
jbe 1f
movb %dl, %dh
subb $8, %dh
1:
addb %dh, %bl
ret
.balign 4
.global _pc_install_irq
_pc_install_irq:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %edi
call common
cmpl $0, IRQ_HOOK(%edi)
jne fail
pushl $IRQ_WRAPPER_LEN
pushl %edi
call __go32_dpmi_lock_code
addl $8, %esp
testl %eax, %eax
jnz fail
pushl $IRQ_STACK_SIZE
call _pc_malloc
popl %edx
testl %eax, %eax
jz fail
addl %edx, %eax
movl %eax, IRQ_STACK(%edi)
movl ___djgpp_ds_alias, %eax
movl %eax, IRQ_STACK+4(%edi)
movl %ss:12(%ebp), %eax
movl %eax, IRQ_HOOK(%edi)
movw $0x0204, %ax
int $0x31
movl %edx, IRQ_OLD(%edi)
movw %cx, IRQ_OLD+4(%edi)
movw $0x0205, %ax
movl %edi, %edx
movl %cs, %ecx
int $0x31
done:
xorl %eax, %eax
popl %edi
popl %ebx
leave
ret
.balign 4
.global _pc_remove_irq
_pc_remove_irq:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %edi
call common
cmpl $0, IRQ_HOOK(%edi)
je fail
movl $0, IRQ_HOOK(%edi)
movw $0x0205, %ax
movl IRQ_OLD(%edi), %edx
movl IRQ_OLD+4(%edi), %ecx
int $0x31
movl IRQ_STACK(%edi), %eax
subl $IRQ_STACK_SIZE, %eax
pushl %eax
call _free
popl %eax
jmp done
#define WRAPPER(x) ; \
.balign 4 ; \
__irq_wrapper_##x: ; \
pushal ; \
pushl %ds ; \
pushl %es ; \
pushl %fs ; \
pushl %gs ; \
movl %ss, %ebx ; \
movl %esp, %esi ; \
lss %cs:__irq_stack_##x, %esp ; \
pushl %ss ; \
pushl %ss ; \
popl %es ; \
popl %ds ; \
movl ___djgpp_dos_sel, %fs ; \
pushl %fs ; \
popl %gs ; \
call *__irq_hook_##x ; \
movl %ebx, %ss ; \
movl %esi, %esp ; \
testl %eax, %eax ; \
popl %gs ; \
popl %fs ; \
popl %es ; \
popl %ds ; \
popal ; \
jz __irq_ignore_##x ; \
__irq_bypass_##x: ; \
ljmp *%cs:__irq_old_##x ; \
__irq_ignore_##x: ; \
iret ; \
.balign 4 ; \
__irq_old_##x: ; \
.long 0, 0 ; \
__irq_hook_##x: ; \
.long 0 ; \
__irq_stack_##x: ; \
.long 0, 0
WRAPPER(0);
WRAPPER(1);
WRAPPER(2);
WRAPPER(3);
WRAPPER(4);
WRAPPER(5);
WRAPPER(6);
WRAPPER(7);
WRAPPER(8);
WRAPPER(9);
WRAPPER(10);
WRAPPER(11);
WRAPPER(12);
WRAPPER(13);
WRAPPER(14);
WRAPPER(15);
|