bios_disk.S revision 1.12 1 1.12 dsl /* $NetBSD: bios_disk.S,v 1.12 2003/03/08 21:09:37 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 /*
59 1.9 dyoung # BIOS call "INT 0x13 Function 0x0" to reset the disk subsystem
60 1.9 dyoung # Call with %ah = 0x0
61 1.9 dyoung # %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
62 1.9 dyoung # Return:
63 1.9 dyoung # %al = 0x0 on success; err code on failure
64 1.9 dyoung */
65 1.9 dyoung ENTRY(biosdiskreset)
66 1.9 dyoung pushl %ebp
67 1.9 dyoung movl %esp, %ebp
68 1.9 dyoung pushl %ebx
69 1.9 dyoung push %edx
70 1.9 dyoung push %edi
71 1.9 dyoung
72 1.9 dyoung movb 8(%ebp), %dl # device
73 1.9 dyoung
74 1.9 dyoung call _C_LABEL(prot_to_real) # enter real mode
75 1.10 dsl .code16
76 1.9 dyoung
77 1.9 dyoung movb $0x0, %ah # subfunction
78 1.9 dyoung int $0x13
79 1.9 dyoung setc %bl
80 1.9 dyoung movb %ah, %bh # save error code
81 1.9 dyoung
82 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
83 1.10 dsl .code32
84 1.9 dyoung
85 1.9 dyoung xorl %eax, %eax
86 1.9 dyoung movw %bx, %ax # return value in %ax
87 1.9 dyoung
88 1.9 dyoung pop %edi
89 1.9 dyoung pop %edx
90 1.9 dyoung popl %ebx
91 1.9 dyoung popl %ebp
92 1.9 dyoung ret
93 1.9 dyoung
94 1.9 dyoung /*
95 1.1 perry # BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
96 1.1 perry # Call with %ah = 0x2
97 1.1 perry # %al = number of sectors
98 1.1 perry # %ch = cylinder
99 1.1 perry # %cl = sector
100 1.1 perry # %dh = head
101 1.1 perry # %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
102 1.1 perry # %es:%bx = segment:offset of buffer
103 1.1 perry # Return:
104 1.1 perry # %al = 0x0 on success; err code on failure
105 1.9 dyoung #
106 1.10 dsl # biosread( dev, cyl, head, sect, count, buff_addr );
107 1.10 dsl #
108 1.9 dyoung # Note: On failure, you must reset the disk with biosdiskreset() before
109 1.9 dyoung # sending another command.
110 1.1 perry */
111 1.1 perry ENTRY(biosread)
112 1.1 perry pushl %ebp
113 1.1 perry movl %esp, %ebp
114 1.1 perry pushl %ebx
115 1.1 perry push %ecx
116 1.1 perry push %edx
117 1.1 perry push %esi
118 1.1 perry push %edi
119 1.1 perry
120 1.1 perry movb 16(%ebp), %dh
121 1.1 perry movw 12(%ebp), %cx
122 1.1 perry xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
123 1.1 perry rorb $2, %cl
124 1.1 perry movb 20(%ebp), %al
125 1.1 perry orb %al, %cl
126 1.1 perry incb %cl # sector; sec starts from 1, not 0
127 1.1 perry movb 8(%ebp), %dl # device
128 1.12 dsl movl 28(%ebp), %ebx # buffer address (may be >64k)
129 1.12 dsl movb 24(%ebp), %al # number of sectors
130 1.1 perry
131 1.1 perry call _C_LABEL(prot_to_real) # enter real mode
132 1.10 dsl .code16
133 1.10 dsl
134 1.12 dsl push %bx
135 1.12 dsl shrl $4, %ebx # max segment
136 1.10 dsl mov %ds, %si
137 1.12 dsl add %si, %bx
138 1.12 dsl mov %bx, %es # %es:%bx now valid buffer address
139 1.12 dsl pop %bx
140 1.12 dsl and $0xf, %bx # and min offset - to avoid overrun
141 1.1 perry
142 1.1 perry movb $0x2, %ah # subfunction
143 1.1 perry int $0x13
144 1.12 dsl setc %al # error code is in %ah
145 1.8 perry
146 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
147 1.10 dsl .code32
148 1.1 perry
149 1.12 dsl andl $0xffff, %eax
150 1.1 perry
151 1.1 perry pop %edi
152 1.1 perry pop %esi
153 1.1 perry pop %edx
154 1.1 perry pop %ecx
155 1.1 perry popl %ebx
156 1.1 perry popl %ebp
157 1.1 perry ret
158 1.1 perry
159 1.1 perry /*
160 1.1 perry #
161 1.6 drochner # get_diskinfo(): return a word that represents the
162 1.6 drochner # max number of sectors, heads and cylinders for this device
163 1.1 perry #
164 1.1 perry */
165 1.1 perry
166 1.1 perry ENTRY(get_diskinfo)
167 1.1 perry pushl %ebp
168 1.1 perry movl %esp, %ebp
169 1.1 perry push %es
170 1.1 perry pushl %ebx
171 1.1 perry push %ecx
172 1.1 perry push %edx
173 1.1 perry push %esi
174 1.1 perry push %edi
175 1.1 perry
176 1.6 drochner movb 8(%ebp), %dl # diskinfo(drive #)
177 1.1 perry
178 1.1 perry call _C_LABEL(prot_to_real) # enter real mode
179 1.10 dsl .code16
180 1.1 perry
181 1.1 perry movb $0x08, %ah # ask for disk info
182 1.1 perry int $0x13
183 1.1 perry jnc ok
184 1.1 perry
185 1.1 perry /*
186 1.1 perry * Urk. Call failed. It is not supported for floppies by old BIOS's.
187 1.1 perry * Guess it's a 15-sector floppy. Initialize all the registers for
188 1.1 perry * documentation, although we only need head and sector counts.
189 1.1 perry */
190 1.1 perry # subb %ah, %ah # %ax = 0
191 1.1 perry # movb %ah, %bh # %bh = 0
192 1.1 perry # movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M
193 1.6 drochner movb $79, %ch # max track
194 1.1 perry movb $15, %cl # max sector
195 1.1 perry movb $1, %dh # max head
196 1.1 perry # movb $1, %dl # # floppy drives installed
197 1.1 perry # es:di = parameter table
198 1.1 perry # carry = 0
199 1.1 perry
200 1.1 perry ok:
201 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
202 1.10 dsl .code32
203 1.7 fvdl
204 1.6 drochner /* form a longword representing all this gunk */
205 1.6 drochner shll $8, %ecx
206 1.6 drochner movb %dh, %cl
207 1.6 drochner
208 1.6 drochner movl %ecx, %eax
209 1.1 perry
210 1.1 perry pop %edi
211 1.1 perry pop %esi
212 1.1 perry pop %edx
213 1.1 perry pop %ecx
214 1.1 perry popl %ebx
215 1.1 perry pop %es
216 1.2 ws popl %ebp
217 1.2 ws ret
218 1.2 ws
219 1.2 ws /*
220 1.2 ws # int13_extension: check for availibility of int13 extensions.
221 1.2 ws */
222 1.2 ws
223 1.2 ws ENTRY(int13_extension)
224 1.2 ws pushl %ebp
225 1.2 ws movl %esp, %ebp
226 1.2 ws pushl %ebx
227 1.2 ws pushl %ecx
228 1.2 ws pushl %edx
229 1.2 ws pushl %esi
230 1.2 ws pushl %edi
231 1.2 ws
232 1.2 ws movb 8(%ebp), %dl # drive #
233 1.2 ws movw $0x55aa, %bx
234 1.2 ws
235 1.2 ws call _C_LABEL(prot_to_real) # enter real mode
236 1.10 dsl .code16
237 1.2 ws
238 1.2 ws movb $0x41, %ah # ask for disk info
239 1.2 ws int $0x13
240 1.3 ws setnc %dl
241 1.2 ws
242 1.10 dsl calll _C_LABEL(real_to_prot) # switch back
243 1.10 dsl .code32
244 1.2 ws
245 1.2 ws xorl %eax, %eax
246 1.2 ws movb %dl, %al # return value in %ax
247 1.2 ws
248 1.2 ws cmpw $0xaa55, %bx
249 1.2 ws sete %dl
250 1.4 ws andb %dl, %al
251 1.2 ws
252 1.4 ws andb %cl, %al
253 1.2 ws
254 1.2 ws popl %edi
255 1.2 ws popl %esi
256 1.2 ws popl %edx
257 1.2 ws popl %ecx
258 1.2 ws popl %ebx
259 1.2 ws popl %ebp
260 1.2 ws ret
261 1.2 ws
262 1.2 ws /*
263 1.2 ws # BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
264 1.2 ws # Call with %ah = 0x42
265 1.10 dsl # %ds:%si = parameter block (data buffer address
266 1.10 dsl # must be a real mode physical address).
267 1.2 ws # %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
268 1.2 ws # Return:
269 1.2 ws # %al = 0x0 on success; err code on failure
270 1.2 ws */
271 1.2 ws ENTRY(biosextread)
272 1.2 ws pushl %ebp
273 1.2 ws movl %esp, %ebp
274 1.2 ws pushl %ebx
275 1.2 ws push %ecx
276 1.2 ws push %edx
277 1.2 ws push %esi
278 1.2 ws push %edi
279 1.2 ws
280 1.2 ws movb 8(%ebp), %dl # device
281 1.2 ws movl 12(%ebp), %esi # parameter block
282 1.2 ws
283 1.2 ws call _C_LABEL(prot_to_real) # enter real mode
284 1.10 dsl .code16
285 1.10 dsl
286 1.10 dsl movl %esi, %eax
287 1.10 dsl shrl $4, %eax
288 1.10 dsl movw %ds, %bx
289 1.10 dsl addw %bx, %ax
290 1.10 dsl movw %ax, %ds
291 1.10 dsl andw $0xf, %si
292 1.2 ws
293 1.2 ws movb $0x42, %ah # subfunction
294 1.5 fvdl int $0x13
295 1.5 fvdl setc %bl
296 1.8 perry movb %ah, %bh # save error code
297 1.5 fvdl
298 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
299 1.10 dsl .code32
300 1.5 fvdl
301 1.5 fvdl xorl %eax, %eax
302 1.8 perry movw %bx, %ax # return value in %ax
303 1.5 fvdl
304 1.5 fvdl pop %edi
305 1.5 fvdl pop %esi
306 1.5 fvdl pop %edx
307 1.5 fvdl pop %ecx
308 1.5 fvdl popl %ebx
309 1.5 fvdl popl %ebp
310 1.5 fvdl ret
311 1.5 fvdl
312 1.5 fvdl ENTRY(int13_getextinfo)
313 1.5 fvdl pushl %ebp
314 1.5 fvdl movl %esp, %ebp
315 1.5 fvdl pushl %ebx
316 1.5 fvdl push %ecx
317 1.5 fvdl push %edx
318 1.5 fvdl push %esi
319 1.5 fvdl push %edi
320 1.5 fvdl
321 1.5 fvdl movb 8(%ebp), %dl # device
322 1.5 fvdl movl 12(%ebp), %esi # parameter block
323 1.5 fvdl movl $0x01a, (%esi) # length (v 1.x)
324 1.5 fvdl
325 1.5 fvdl call _C_LABEL(prot_to_real) # enter real mode
326 1.10 dsl .code16
327 1.10 dsl
328 1.10 dsl movl %esi, %eax
329 1.10 dsl shrl $4, %eax
330 1.10 dsl andw $0xf, %si
331 1.10 dsl movw %ds, %bx
332 1.10 dsl addw %bx, %ax
333 1.10 dsl movw %ax, %ds
334 1.5 fvdl
335 1.5 fvdl movb $0x48, %ah # subfunction
336 1.2 ws int $0x13
337 1.2 ws setc %bl
338 1.2 ws
339 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
340 1.10 dsl .code32
341 1.2 ws
342 1.2 ws xorl %eax, %eax
343 1.2 ws movb %bl, %al # return value in %ax
344 1.2 ws
345 1.2 ws pop %edi
346 1.2 ws pop %esi
347 1.2 ws pop %edx
348 1.2 ws pop %ecx
349 1.2 ws popl %ebx
350 1.1 perry popl %ebp
351 1.1 perry ret
352