bios_disk.S revision 1.10 1 1.10 dsl /* $NetBSD: bios_disk.S,v 1.10 2003/02/01 14:48:17 dsl Exp $ */
2 1.1 perry
3 1.1 perry /*
4 1.1 perry * Ported to boot 386BSD by Julian Elischer (julian (at) tfs.com) Sept 1992
5 1.1 perry *
6 1.1 perry * Mach Operating System
7 1.1 perry * Copyright (c) 1992, 1991 Carnegie Mellon University
8 1.1 perry * All Rights Reserved.
9 1.1 perry *
10 1.1 perry * Permission to use, copy, modify and distribute this software and its
11 1.1 perry * documentation is hereby granted, provided that both the copyright
12 1.1 perry * notice and this permission notice appear in all copies of the
13 1.1 perry * software, derivative works or modified versions, and any portions
14 1.1 perry * thereof, and that both notices appear in supporting documentation.
15 1.1 perry *
16 1.1 perry * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 1.1 perry * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
18 1.1 perry * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 1.1 perry *
20 1.1 perry * Carnegie Mellon requests users of this software to return to
21 1.1 perry *
22 1.1 perry * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
23 1.1 perry * School of Computer Science
24 1.1 perry * Carnegie Mellon University
25 1.1 perry * Pittsburgh PA 15213-3890
26 1.1 perry *
27 1.1 perry * any improvements or extensions that they make and grant Carnegie Mellon
28 1.1 perry * the rights to redistribute these changes.
29 1.1 perry */
30 1.1 perry
31 1.1 perry /*
32 1.1 perry Copyright 1988, 1989, 1990, 1991, 1992
33 1.1 perry by Intel Corporation, Santa Clara, California.
34 1.1 perry
35 1.1 perry All Rights Reserved
36 1.1 perry
37 1.1 perry Permission to use, copy, modify, and distribute this software and
38 1.1 perry its documentation for any purpose and without fee is hereby
39 1.1 perry granted, provided that the above copyright notice appears in all
40 1.1 perry copies and that both the copyright notice and this permission notice
41 1.1 perry appear in supporting documentation, and that the name of Intel
42 1.1 perry not be used in advertising or publicity pertaining to distribution
43 1.1 perry of the software without specific, written prior permission.
44 1.1 perry
45 1.1 perry INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
46 1.1 perry INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
47 1.1 perry IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
48 1.1 perry CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
49 1.1 perry LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
50 1.1 perry NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
51 1.1 perry WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
52 1.1 perry */
53 1.1 perry
54 1.1 perry /* extracted from netbsd:sys/arch/i386/boot/bios.S */
55 1.1 perry
56 1.1 perry #include <machine/asm.h>
57 1.1 perry
58 1.1 perry #define addr32 .byte 0x67
59 1.1 perry #define data32 .byte 0x66
60 1.1 perry
61 1.1 perry /*
62 1.9 dyoung # BIOS call "INT 0x13 Function 0x0" to reset the disk subsystem
63 1.9 dyoung # Call with %ah = 0x0
64 1.9 dyoung # %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
65 1.9 dyoung # Return:
66 1.9 dyoung # %al = 0x0 on success; err code on failure
67 1.9 dyoung */
68 1.9 dyoung ENTRY(biosdiskreset)
69 1.9 dyoung pushl %ebp
70 1.9 dyoung movl %esp, %ebp
71 1.9 dyoung pushl %ebx
72 1.9 dyoung push %edx
73 1.9 dyoung push %edi
74 1.9 dyoung
75 1.9 dyoung movb 8(%ebp), %dl # device
76 1.9 dyoung
77 1.9 dyoung call _C_LABEL(prot_to_real) # enter real mode
78 1.10 dsl .code16
79 1.9 dyoung
80 1.9 dyoung movb $0x0, %ah # subfunction
81 1.9 dyoung int $0x13
82 1.9 dyoung setc %bl
83 1.9 dyoung movb %ah, %bh # save error code
84 1.9 dyoung
85 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
86 1.10 dsl .code32
87 1.9 dyoung
88 1.9 dyoung xorl %eax, %eax
89 1.9 dyoung movw %bx, %ax # return value in %ax
90 1.9 dyoung
91 1.9 dyoung pop %edi
92 1.9 dyoung pop %edx
93 1.9 dyoung popl %ebx
94 1.9 dyoung popl %ebp
95 1.9 dyoung ret
96 1.9 dyoung
97 1.9 dyoung /*
98 1.1 perry # BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
99 1.1 perry # Call with %ah = 0x2
100 1.1 perry # %al = number of sectors
101 1.1 perry # %ch = cylinder
102 1.1 perry # %cl = sector
103 1.1 perry # %dh = head
104 1.1 perry # %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
105 1.1 perry # %es:%bx = segment:offset of buffer
106 1.1 perry # Return:
107 1.1 perry # %al = 0x0 on success; err code on failure
108 1.9 dyoung #
109 1.10 dsl # biosread( dev, cyl, head, sect, count, buff_addr );
110 1.10 dsl #
111 1.9 dyoung # Note: On failure, you must reset the disk with biosdiskreset() before
112 1.9 dyoung # sending another command.
113 1.1 perry */
114 1.1 perry ENTRY(biosread)
115 1.1 perry pushl %ebp
116 1.1 perry movl %esp, %ebp
117 1.1 perry pushl %ebx
118 1.1 perry push %ecx
119 1.1 perry push %edx
120 1.1 perry push %esi
121 1.1 perry push %edi
122 1.1 perry
123 1.1 perry movb 16(%ebp), %dh
124 1.1 perry movw 12(%ebp), %cx
125 1.1 perry xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
126 1.1 perry rorb $2, %cl
127 1.1 perry movb 20(%ebp), %al
128 1.1 perry orb %al, %cl
129 1.1 perry incb %cl # sector; sec starts from 1, not 0
130 1.1 perry movb 8(%ebp), %dl # device
131 1.1 perry
132 1.1 perry call _C_LABEL(prot_to_real) # enter real mode
133 1.10 dsl .code16
134 1.10 dsl
135 1.10 dsl movl 28(%bp), %ebx # buffer address (may be >64k)
136 1.10 dsl movl %ebx, %eax
137 1.10 dsl shrl $4, %eax # max segment
138 1.10 dsl andl $0xf, %ebx # and min offset - to avoid overrun
139 1.10 dsl mov %ds, %si
140 1.10 dsl add %si, %ax
141 1.10 dsl mov %ax, %es # %es:%bx now valid buffer address
142 1.1 perry
143 1.1 perry movb $0x2, %ah # subfunction
144 1.10 dsl movb 24(%bp), %al # number of sectors
145 1.1 perry int $0x13
146 1.1 perry setc %bl
147 1.8 perry movb %ah, %bh # save error code
148 1.8 perry
149 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
150 1.10 dsl .code32
151 1.1 perry
152 1.1 perry xorl %eax, %eax
153 1.8 perry movw %bx, %ax # return value in %ax
154 1.1 perry
155 1.1 perry pop %edi
156 1.1 perry pop %esi
157 1.1 perry pop %edx
158 1.1 perry pop %ecx
159 1.1 perry popl %ebx
160 1.1 perry popl %ebp
161 1.1 perry ret
162 1.1 perry
163 1.1 perry /*
164 1.1 perry #
165 1.6 drochner # get_diskinfo(): return a word that represents the
166 1.6 drochner # max number of sectors, heads and cylinders for this device
167 1.1 perry #
168 1.1 perry */
169 1.1 perry
170 1.1 perry ENTRY(get_diskinfo)
171 1.1 perry pushl %ebp
172 1.1 perry movl %esp, %ebp
173 1.1 perry push %es
174 1.1 perry pushl %ebx
175 1.1 perry push %ecx
176 1.1 perry push %edx
177 1.1 perry push %esi
178 1.1 perry push %edi
179 1.1 perry
180 1.6 drochner movb 8(%ebp), %dl # diskinfo(drive #)
181 1.1 perry
182 1.1 perry call _C_LABEL(prot_to_real) # enter real mode
183 1.10 dsl .code16
184 1.1 perry
185 1.1 perry movb $0x08, %ah # ask for disk info
186 1.1 perry int $0x13
187 1.1 perry jnc ok
188 1.1 perry
189 1.1 perry /*
190 1.1 perry * Urk. Call failed. It is not supported for floppies by old BIOS's.
191 1.1 perry * Guess it's a 15-sector floppy. Initialize all the registers for
192 1.1 perry * documentation, although we only need head and sector counts.
193 1.1 perry */
194 1.1 perry # subb %ah, %ah # %ax = 0
195 1.1 perry # movb %ah, %bh # %bh = 0
196 1.1 perry # movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M
197 1.6 drochner movb $79, %ch # max track
198 1.1 perry movb $15, %cl # max sector
199 1.1 perry movb $1, %dh # max head
200 1.1 perry # movb $1, %dl # # floppy drives installed
201 1.1 perry # es:di = parameter table
202 1.1 perry # carry = 0
203 1.1 perry
204 1.1 perry ok:
205 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
206 1.10 dsl .code32
207 1.7 fvdl
208 1.6 drochner /* form a longword representing all this gunk */
209 1.6 drochner shll $8, %ecx
210 1.6 drochner movb %dh, %cl
211 1.6 drochner
212 1.6 drochner movl %ecx, %eax
213 1.1 perry
214 1.1 perry pop %edi
215 1.1 perry pop %esi
216 1.1 perry pop %edx
217 1.1 perry pop %ecx
218 1.1 perry popl %ebx
219 1.1 perry pop %es
220 1.2 ws popl %ebp
221 1.2 ws ret
222 1.2 ws
223 1.2 ws /*
224 1.2 ws # int13_extension: check for availibility of int13 extensions.
225 1.2 ws */
226 1.2 ws
227 1.2 ws ENTRY(int13_extension)
228 1.2 ws pushl %ebp
229 1.2 ws movl %esp, %ebp
230 1.2 ws pushl %ebx
231 1.2 ws pushl %ecx
232 1.2 ws pushl %edx
233 1.2 ws pushl %esi
234 1.2 ws pushl %edi
235 1.2 ws
236 1.2 ws movb 8(%ebp), %dl # drive #
237 1.2 ws movw $0x55aa, %bx
238 1.2 ws
239 1.2 ws call _C_LABEL(prot_to_real) # enter real mode
240 1.10 dsl .code16
241 1.2 ws
242 1.2 ws movb $0x41, %ah # ask for disk info
243 1.2 ws int $0x13
244 1.3 ws setnc %dl
245 1.2 ws
246 1.10 dsl calll _C_LABEL(real_to_prot) # switch back
247 1.10 dsl .code32
248 1.2 ws
249 1.2 ws xorl %eax, %eax
250 1.2 ws movb %dl, %al # return value in %ax
251 1.2 ws
252 1.2 ws cmpw $0xaa55, %bx
253 1.2 ws sete %dl
254 1.4 ws andb %dl, %al
255 1.2 ws
256 1.4 ws andb %cl, %al
257 1.2 ws
258 1.2 ws popl %edi
259 1.2 ws popl %esi
260 1.2 ws popl %edx
261 1.2 ws popl %ecx
262 1.2 ws popl %ebx
263 1.2 ws popl %ebp
264 1.2 ws ret
265 1.2 ws
266 1.2 ws /*
267 1.2 ws # BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
268 1.2 ws # Call with %ah = 0x42
269 1.10 dsl # %ds:%si = parameter block (data buffer address
270 1.10 dsl # must be a real mode physical address).
271 1.2 ws # %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
272 1.2 ws # Return:
273 1.2 ws # %al = 0x0 on success; err code on failure
274 1.2 ws */
275 1.2 ws ENTRY(biosextread)
276 1.2 ws pushl %ebp
277 1.2 ws movl %esp, %ebp
278 1.2 ws pushl %ebx
279 1.2 ws push %ecx
280 1.2 ws push %edx
281 1.2 ws push %esi
282 1.2 ws push %edi
283 1.2 ws
284 1.2 ws movb 8(%ebp), %dl # device
285 1.2 ws movl 12(%ebp), %esi # parameter block
286 1.2 ws
287 1.2 ws call _C_LABEL(prot_to_real) # enter real mode
288 1.10 dsl .code16
289 1.10 dsl
290 1.10 dsl movl %esi, %eax
291 1.10 dsl shrl $4, %eax
292 1.10 dsl movw %ds, %bx
293 1.10 dsl addw %bx, %ax
294 1.10 dsl movw %ax, %ds
295 1.10 dsl andw $0xf, %si
296 1.2 ws
297 1.2 ws movb $0x42, %ah # subfunction
298 1.5 fvdl int $0x13
299 1.5 fvdl setc %bl
300 1.8 perry movb %ah, %bh # save error code
301 1.5 fvdl
302 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
303 1.10 dsl .code32
304 1.5 fvdl
305 1.5 fvdl xorl %eax, %eax
306 1.8 perry movw %bx, %ax # return value in %ax
307 1.5 fvdl
308 1.5 fvdl pop %edi
309 1.5 fvdl pop %esi
310 1.5 fvdl pop %edx
311 1.5 fvdl pop %ecx
312 1.5 fvdl popl %ebx
313 1.5 fvdl popl %ebp
314 1.5 fvdl ret
315 1.5 fvdl
316 1.5 fvdl ENTRY(int13_getextinfo)
317 1.5 fvdl pushl %ebp
318 1.5 fvdl movl %esp, %ebp
319 1.5 fvdl pushl %ebx
320 1.5 fvdl push %ecx
321 1.5 fvdl push %edx
322 1.5 fvdl push %esi
323 1.5 fvdl push %edi
324 1.5 fvdl
325 1.5 fvdl movb 8(%ebp), %dl # device
326 1.5 fvdl movl 12(%ebp), %esi # parameter block
327 1.5 fvdl movl $0x01a, (%esi) # length (v 1.x)
328 1.5 fvdl
329 1.5 fvdl call _C_LABEL(prot_to_real) # enter real mode
330 1.10 dsl .code16
331 1.10 dsl
332 1.10 dsl movl %esi, %eax
333 1.10 dsl shrl $4, %eax
334 1.10 dsl andw $0xf, %si
335 1.10 dsl movw %ds, %bx
336 1.10 dsl addw %bx, %ax
337 1.10 dsl movw %ax, %ds
338 1.5 fvdl
339 1.5 fvdl movb $0x48, %ah # subfunction
340 1.2 ws int $0x13
341 1.2 ws setc %bl
342 1.2 ws
343 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
344 1.10 dsl .code32
345 1.2 ws
346 1.2 ws xorl %eax, %eax
347 1.2 ws movb %bl, %al # return value in %ax
348 1.2 ws
349 1.2 ws pop %edi
350 1.2 ws pop %esi
351 1.2 ws pop %edx
352 1.2 ws pop %ecx
353 1.2 ws popl %ebx
354 1.1 perry popl %ebp
355 1.1 perry ret
356