[freeldr] Move custom.c, drivemap.c/h, miscboot.c/h to i386 directories
[reactos.git] / reactos / boot / freeldr / freeldr / arch / i386 / i386pnp.S
1 /*
2 * FreeLoader
3 * Copyright (C) 2003 Eric Kohl
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 .text
21 .code16
22
23 #define ASM
24
25 #include <arch.h>
26
27
28 /*
29 * U32 PnpBiosSupported(VOID);
30 *
31 * RETURNS:
32 */
33 _pnp_bios_entry_point:
34 .long 0
35 _pnp_bios_data_segment:
36 .word 0
37
38 EXTERN(_PnpBiosSupported)
39 .code32
40
41 pushl %edi
42 pushl %esi
43 pushl %ecx
44 pushl %edx
45
46 xorl %edi,%edi
47
48 /* init esi */
49 movl $0xF0000,%esi
50
51 pnp_again:
52 movl (%esi),%eax
53 cmp $0x506E5024,%eax /* "$PnP" */
54 je pnp_found
55
56 cmp $0xFFFF0,%esi
57 je pnp_not_found
58
59 pnp_add:
60 addl $0x10,%esi
61 jmp pnp_again
62
63 pnp_found:
64 /* first calculate the checksum */
65 pushl %esi
66
67 pushl $0x21
68 popl %ecx
69 xorl %edx, %edx
70
71 pnp_loop:
72 lodsb
73 addb %al,%dl
74 loopl pnp_loop
75
76 testb %dl, %dl
77 popl %esi
78 jnz pnp_add
79
80 movl %esi,%edi
81
82 /* Calculate the bios entry point (far pointer) */
83 xorl %eax,%eax
84 movw 0x0F(%esi),%ax
85 shll $16,%eax
86 movw 0x0D(%esi),%ax
87 movl %eax,_pnp_bios_entry_point
88
89 /* Store bios data segment */
90 movw 0x1B(%esi),%ax
91 movw %ax,_pnp_bios_data_segment
92
93 pnp_not_found:
94 movl %edi,%eax
95
96 popl %edx
97 popl %ecx
98 popl %esi
99 popl %edi
100
101 ret
102
103
104 /*
105 * U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize, U32 *NodeCount);
106 *
107 * RETURNS:
108 */
109 _pnp_result:
110 .long 0
111 _pnp_node_size:
112 .word 0
113 _pnp_node_count:
114 .word 0
115
116 EXTERN(_PnpBiosGetDeviceNodeCount)
117 .code32
118
119 pushl %ebp
120 movl %esp,%ebp
121
122 pushal
123 push %es
124
125 call switch_to_real
126 .code16
127
128 movw _pnp_bios_data_segment,%ax
129 pushw %ax
130
131 pushw %cs
132 movw $(_pnp_node_size),%ax
133 pushw %ax
134
135 pushw %cs
136 movw $(_pnp_node_count),%ax
137 pushw %ax
138
139 pushw $0
140
141 lcall *_pnp_bios_entry_point
142 addw $12,%sp
143
144 movzwl %ax,%ecx
145 movl %ecx,_pnp_result
146
147
148 call switch_to_prot
149 .code32
150
151 movl 0x08(%ebp),%esi
152 movw _pnp_node_size,%ax
153 movzwl %ax,%ecx
154 movl %ecx, (%esi)
155
156 movl 0x0C(%ebp),%esi
157 movw _pnp_node_count,%ax
158 movzwl %ax,%ecx
159 movl %eax, (%esi)
160
161 pop %es
162 popal
163
164 movl %ebp,%esp
165 popl %ebp
166
167 movl _pnp_result,%eax
168
169 ret
170
171
172 /*
173 * U32 PnpBiosGetDeviceNode(U8 *NodeId, U8 *NodeBuffer);
174 *
175 * RETURNS:
176 */
177 _pnp_buffer_segment:
178 .word 0
179 _pnp_buffer_offset:
180 .word 0
181
182 _pnp_node_number:
183 .byte 0
184
185 EXTERN(_PnpBiosGetDeviceNode)
186 .code32
187
188 pushl %ebp
189 movl %esp,%ebp
190
191 pushal
192 push %es
193
194 /* get current node number */
195 movl 0x08(%ebp),%esi
196 movb (%esi),%al
197 movb %al,_pnp_node_number
198
199 /* convert pointer to node buffer to segment/offset */
200 movl 0x0C(%ebp),%eax
201 shrl $4,%eax
202 andl $0xf000,%eax
203 movw %ax,_pnp_buffer_segment
204 movl 0x0C(%ebp),%eax
205 andl $0xffff,%eax
206 movw %ax,_pnp_buffer_offset
207
208 call switch_to_real
209 .code16
210
211 /* push bios segment */
212 movw _pnp_bios_data_segment,%ax
213 pushw %ax
214
215 /* push control flag */
216 pushw $0x0001
217
218 /* push pointer to node buffer (segment/offset) */
219 movw _pnp_buffer_segment,%ax
220 pushw %ax
221 movw _pnp_buffer_offset,%ax
222 pushw %ax
223
224 /* push pointer to node number (segment/offset) */
225 pushw %cs
226 movw $(_pnp_node_number),%ax
227 pushw %ax
228
229 /* push function number */
230 pushw $1
231
232 /* call entry point */
233 lcall *_pnp_bios_entry_point
234 addw $14,%sp
235
236 movzwl %ax,%ecx
237 movl %ecx,_pnp_result
238
239 call switch_to_prot
240 .code32
241
242 /* update node number */
243 movl 0x08(%ebp),%esi
244 movb _pnp_node_number,%al
245 movb %al,(%esi)
246
247 pop %es
248 popal
249
250 movl %ebp,%esp
251 popl %ebp
252
253 movl _pnp_result,%eax
254
255 ret
256
257 /* EOF */