bios_disk.S revision 1.17 1 1.17 junyoung /* $NetBSD: bios_disk.S,v 1.17 2005/06/29 18:50:38 junyoung 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.14 junyoung *
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.14 junyoung *
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.14 junyoung *
20 1.1 perry * Carnegie Mellon requests users of this software to return to
21 1.14 junyoung *
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.14 junyoung *
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.14 junyoung 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.15 junyoung * BIOS call "INT 0x13 Function 0x0" to reset the disk subsystem
60 1.15 junyoung * Call with %ah = 0x0
61 1.15 junyoung * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
62 1.15 junyoung * Return:
63 1.15 junyoung * %al = 0x0 on success; err code on failure
64 1.15 junyoung */
65 1.17 junyoung ENTRY(biosdisk_reset)
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.15 junyoung * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
96 1.15 junyoung * Call with %ah = 0x2
97 1.15 junyoung * %al = number of sectors
98 1.15 junyoung * %ch = cylinder
99 1.15 junyoung * %cl = sector
100 1.15 junyoung * %dh = head
101 1.15 junyoung * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
102 1.15 junyoung * %es:%bx = segment:offset of buffer
103 1.15 junyoung * Return:
104 1.15 junyoung * %al = 0x0 on success; err code on failure
105 1.15 junyoung *
106 1.17 junyoung * biosdisk_read(dev, cyl, head, sect, count, buff_addr);
107 1.15 junyoung *
108 1.17 junyoung * Note: On failure, you must reset the disk with biosdisk_reset() before
109 1.15 junyoung * sending another command.
110 1.15 junyoung */
111 1.17 junyoung ENTRY(biosdisk_read)
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.14 junyoung
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.17 junyoung * biosdisk_getinfo(int dev): return a word that represents the
161 1.15 junyoung * max number of sectors, heads and cylinders for this device
162 1.15 junyoung */
163 1.17 junyoung ENTRY(biosdisk_getinfo)
164 1.1 perry pushl %ebp
165 1.1 perry movl %esp, %ebp
166 1.1 perry push %es
167 1.1 perry pushl %ebx
168 1.1 perry push %ecx
169 1.1 perry push %edx
170 1.1 perry push %esi
171 1.1 perry push %edi
172 1.1 perry
173 1.6 drochner movb 8(%ebp), %dl # diskinfo(drive #)
174 1.1 perry
175 1.1 perry call _C_LABEL(prot_to_real) # enter real mode
176 1.10 dsl .code16
177 1.1 perry
178 1.16 junyoung push %dx # save drive #
179 1.1 perry movb $0x08, %ah # ask for disk info
180 1.1 perry int $0x13
181 1.16 junyoung pop %bx # restore drive #
182 1.1 perry jnc ok
183 1.1 perry
184 1.16 junyoung testb $0x80, %bl # is it a hard disk?
185 1.16 junyoung jnz ok
186 1.16 junyoung
187 1.1 perry /*
188 1.1 perry * Urk. Call failed. It is not supported for floppies by old BIOS's.
189 1.1 perry * Guess it's a 15-sector floppy. Initialize all the registers for
190 1.1 perry * documentation, although we only need head and sector counts.
191 1.1 perry */
192 1.16 junyoung xorw %ax, %ax # set status to success
193 1.1 perry # movb %ah, %bh # %bh = 0
194 1.1 perry # movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M
195 1.6 drochner movb $79, %ch # max track
196 1.1 perry movb $15, %cl # max sector
197 1.1 perry movb $1, %dh # max head
198 1.1 perry # movb $1, %dl # # floppy drives installed
199 1.1 perry # es:di = parameter table
200 1.1 perry # carry = 0
201 1.1 perry
202 1.1 perry ok:
203 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
204 1.10 dsl .code32
205 1.7 fvdl
206 1.6 drochner /* form a longword representing all this gunk */
207 1.16 junyoung shrl $8, %eax # clear unnecessary bits
208 1.16 junyoung shll $24, %eax
209 1.16 junyoung shll $16, %ecx # do the same for %ecx
210 1.16 junyoung shrl $8, %ecx
211 1.16 junyoung movb %dh, %cl # max head
212 1.16 junyoung orl %ecx, %eax # return value in %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.17 junyoung * int biosdisk_int13ext(int dev):
225 1.17 junyoung * check for availibility of int13 extensions.
226 1.15 junyoung */
227 1.17 junyoung ENTRY(biosdisk_int13ext)
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.15 junyoung * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
268 1.15 junyoung * Call with %ah = 0x42
269 1.15 junyoung * %ds:%si = parameter block (data buffer address
270 1.15 junyoung * must be a real mode physical address).
271 1.15 junyoung * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
272 1.15 junyoung * Return:
273 1.15 junyoung * %al = 0x0 on success; err code on failure
274 1.15 junyoung */
275 1.17 junyoung ENTRY(biosdisk_extread)
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.17 junyoung ENTRY(biosdisk_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
328 1.5 fvdl call _C_LABEL(prot_to_real) # enter real mode
329 1.10 dsl .code16
330 1.10 dsl
331 1.10 dsl movl %esi, %eax
332 1.10 dsl shrl $4, %eax
333 1.10 dsl andw $0xf, %si
334 1.10 dsl movw %ds, %bx
335 1.10 dsl addw %bx, %ax
336 1.10 dsl movw %ax, %ds
337 1.5 fvdl
338 1.5 fvdl movb $0x48, %ah # subfunction
339 1.2 ws int $0x13
340 1.2 ws setc %bl
341 1.2 ws
342 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
343 1.10 dsl .code32
344 1.2 ws
345 1.2 ws xorl %eax, %eax
346 1.2 ws movb %bl, %al # return value in %ax
347 1.2 ws
348 1.2 ws pop %edi
349 1.2 ws pop %esi
350 1.2 ws pop %edx
351 1.2 ws pop %ecx
352 1.2 ws popl %ebx
353 1.1 perry popl %ebp
354 1.1 perry ret
355