Remove PC98 and Alpha support.
[dragonfly.git] / sys / boot / pc98 / boot2 / bios.S
1 /*
2  * Mach Operating System
3  * Copyright (c) 1992, 1991 Carnegie Mellon University
4  * All Rights Reserved.
5  * 
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  * 
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  * 
16  * Carnegie Mellon requests users of this software to return to
17  * 
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  * 
23  * any improvements or extensions that they make and grant Carnegie Mellon
24  * the rights to redistribute these changes.
25  *
26  *      from: Mach, Revision 2.2  92/04/04  11:34:26  rpd
27  * $FreeBSD: src/sys/boot/pc98/boot2/bios.S,v 1.4 2003/01/06 13:43:13 nyan Exp $
28  * $DragonFly: src/sys/boot/pc98/boot2/Attic/bios.S,v 1.3 2003/11/10 06:08:38 dillon Exp $
29  */
30
31 /*
32   Copyright 1988, 1989, 1990, 1991, 1992 
33    by Intel Corporation, Santa Clara, California.
34
35                 All Rights Reserved
36
37 Permission to use, copy, modify, and distribute this software and
38 its documentation for any purpose and without fee is hereby
39 granted, provided that the above copyright notice appears in all
40 copies and that both the copyright notice and this permission notice
41 appear in supporting documentation, and that the name of Intel
42 not be used in advertising or publicity pertaining to distribution
43 of the software without specific, written prior permission.
44
45 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
46 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
47 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
48 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
49 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
50 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
51 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
52 */
53 /*
54  * Ported to PC-9801 by Yoshio Kimura
55  */
56
57 /*
58  * Extensions for El Torito CD-ROM booting:
59  *
60  * Copyright © 1997 Pluto Technologies International, Inc.  Boulder CO
61  * Copyright © 1997 interface business GmbH, Dresden.
62  *      All rights reserved.
63  *
64  * This code has been written by Jörg Wunsch, Dresden.
65  * Direct comments to <joerg_wunsch@interface-business.de>.
66  *
67  * Redistribution and use in source and binary forms, with or without
68  * modification, are permitted provided that the following conditions
69  * are met:
70  * 1. Redistributions of source code must retain the above copyright
71  *    notice, this list of conditions and the following disclaimer.
72  * 2. Redistributions in binary form must reproduce the above copyright
73  *    notice, this list of conditions and the following disclaimer in the
74  *    documentation and/or other materials provided with the distribution.
75  *
76  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
77  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
80  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
81  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
82  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
83  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
84  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
85  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
86  * POSSIBILITY OF SUCH DAMAGE.
87  *
88  */
89
90         .file   "bios.s"
91
92 #include "asm.h"
93         .text
94
95 #ifndef CDBOOT
96
97 /*
98  *  PC-9801/PC-9821 SCSI MO booting
99  *    2002/06/05-07/03 Kawanobe Koh <kawanobe@st.rim.or.jp>
100  *
101  */
102 scsi_hd:
103         .code16
104         push    %cx
105         push    %ds
106         mov     %bl, %cl                /* UA */
107         and     $0x0F, %cl
108         xor     %ax, %ax
109         mov     %ax, %ds
110         mov     (0x0482), %al           /* SCSI HD equipment bits */
111         shr     %cl, %al
112         pop     %ds
113         pop     %cx
114         test    $1, %al
115         ret
116
117 /*
118  * biosread(dev, cyl, head, sec, nsec, offset)
119  *      Read "nsec" sectors from disk to offset "offset" in boot segment
120  * BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory
121  *      Call with       %ah = 0xd6(for floppy disk) or 0x06(for hard disk)
122  *                      %al = DA/UA
123  *                      %bx = data length
124  *                      %ch = sector size(for floppy) or cylinder(for hard)
125  *                      %cl = cylinder
126  *                      %dh = head
127  *                      %dl = sector
128  *                      %es:%bp = segment:offset of buffer
129  *      Return:         
130  *                      %al = 0x0 on success; err code on failure
131  */
132
133 ENTRY(biosread)
134         .code32
135         push    %ebp
136         mov     %esp, %ebp
137
138         push    %ebx
139         push    %esi
140         push    %edi
141
142         mov     0x08(%ebp), %bl         /* (byte) DA/UA */
143         mov     0x0C(%ebp), %ecx        /* (word) cylinder */
144         mov     0x10(%ebp), %dh         /* (byte) head */
145         mov     0x14(%ebp), %dl         /* (byte) sector */
146         mov     0x18(%ebp), %esi        /* (byte) number of sectors */
147         mov     0x1C(%ebp), %edi        /* (word) destination offset */
148
149         /* prot_to_real will set %es to BOOTSEG */
150         call    EXT(prot_to_real)       /* enter real mode */
151         .code16
152         mov     $0x06, %bh              /* read data function */
153         mov     %bl, %al                /* DA */
154         and     $0xF0, %al
155         cmp     $0x30, %al              /* 1440KB FD */
156         jz      read_floppy
157         cmp     $0x90, %al              /* 1200KB FD */
158         jz      read_floppy
159         cmp     $0xA0, %al              /* SCSI HD or MO */
160         jnz     read_next
161         call    scsi_hd
162         jnz     read_next
163 read_linear:
164         mov     %dh, %al                /* change to linear sector */
165         shl     $5, %al                 /* multiply by 32 sector per track */
166         add     %dl, %al
167         xor     %dh, %dh                /* higher 16 bits into %dx */
168         mov     %ch, %dl
169         mov     %cl, %ch                /* lower 16 bits into %cx */
170         mov     %al, %cl
171         and     $0x7F, %bl              /* linear access DA/UA */
172         jmp     read_next
173 read_floppy:
174         inc     %dx                     /* sector address begins from one */
175         mov     $0x02, %ch              /* 512 bytes sector */
176         mov     $0xD6, %bh              /* MT MFM retry seek */
177 read_next:
178         mov     %si, %ax                /* number of sectors */
179         shl     $9, %ax                 /* multiply by 512 bytes */
180         xchg    %bx, %ax
181         mov     %di, %bp                /* destination offset */
182         int     $0x1B                   /* disk bios call */
183         jc      read_end
184         xor     %ax, %ax
185 read_end:
186         mov     %ax, %bx                /* save return value */
187
188         .code32
189         data32
190         call    EXT(real_to_prot)       /* back to protected mode */
191
192         xor     %eax, %eax
193         mov     %bh, %al                /* return value in %eax */
194
195         pop     %edi
196         pop     %esi
197         pop     %ebx
198         pop     %ebp
199
200         ret
201
202 #else /* CDBOOT */
203
204
205 /*
206  * int
207  * getbootspec(struct specpacket *offset)
208  *
209  * Read CD-ROM boot specification packet to "offset".
210  */
211 ENTRY(getbootspec)
212         push    %ebp
213         mov     %esp, %ebp
214
215         push    %esi
216         push    %ebx
217
218         movw    0x8(%ebp), %si
219         mov     $0x7f, %edx
220
221         /* prot_to_real will set %es to BOOTSEG */
222         call    EXT(prot_to_real)       /* enter real mode */
223         movw    $0x4b01, %ax            /* (do not) terminate disk emulation */
224         movb    $0x7f, %dl              /* any drive */
225
226         sti
227         int     $0x13
228         cli
229
230         /* save return value (actually movw %ax, %bx) */
231         mov     %eax, %ebx
232
233         data32
234         call    EXT(real_to_prot)       /* back to protected mode */
235
236         xor     %eax, %eax
237         movb    %bh, %al                /* return value in %ax */
238
239         pop     %ebx
240         pop     %esi
241         pop     %ebp
242
243         ret
244
245
246 /*
247  * int
248  * biosreadlba(struct daddrpacket *daddr)
249  *      Read sectors using the BIOS "read extended" function
250  * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
251  *      Call with       %ah = 0x42
252  *                      %dl = drive (0x0 for floppy disk, or emulated CD)
253  *                      %ds:%si = ptr to disk address packet
254  *      Return:
255  *                      %ah = 0x0 on success; err code on failure
256  */
257
258 ENTRY(biosreadlba)
259         push    %ebp
260         mov     %esp, %ebp
261
262         push    %ebx
263         push    %esi
264
265         movw    8(%ebp), %si
266         movl    $0, %edx                /* emulated CD is always drive 0 */
267
268         /* prot_to_real will set %es to BOOTSEG */
269         call    EXT(prot_to_real)       /* enter real mode */
270         movw    $0x4200, %ax            /* subfunction */
271         movb    $0, %dl
272
273         sti
274         int     $0x13
275         cli
276
277         /* save return value (actually movw %ax, %bx) */
278         mov     %eax, %ebx
279
280         data32
281         call    EXT(real_to_prot)       /* back to protected mode */
282
283         xor     %eax, %eax
284         movb    %bh, %al                /* return value in %ax */
285
286         pop     %esi
287         pop     %ebx
288         pop     %ebp
289
290         ret
291
292 #endif /* !CDBOOT */
293
294 /*
295  * getc()
296  * BIOS call "INT 18H Function 00H" to read character from keyboard
297  *      Call with       %ah = 0x0
298  *      Return:         %ah = keyboard scan code
299  *                      %al = ASCII character
300  */
301
302 ENTRY(getc)
303         .code32
304         push    %ebp
305         mov     %esp, %ebp
306         push    %ebx                    /* save %ebx */
307         push    %esi
308         push    %edi
309
310         call    EXT(prot_to_real)
311         .code16
312
313         movb    $0x0, %ah
314         int     $0x18
315
316         movb    %al, %bl                /* real_to_prot uses %eax */
317
318         .code32
319         data32
320         call    EXT(real_to_prot)
321
322         xor     %eax, %eax
323         movb    %bl, %al
324
325         pop     %edi
326         pop     %esi
327         pop     %ebx
328         pop     %ebp
329         ret
330 /*
331  * ischar()
332  *      if there is a character pending, return it; otherwise return 0
333  * BIOS call "INT 18H Function 01H" to check whether a character is pending
334  *      Call with       %ah = 0x1
335  *      Return:
336  *              If key waiting to be input:
337  *                      %ah = keyboard scan code
338  *                      %al = ASCII character
339  *                      %bh = 1
340  *              else
341  *                      %bh = 0
342  */
343 ENTRY(ischar)
344         .code32
345         push    %ebp
346         mov     %esp, %ebp
347         push    %ebx
348         push    %esi
349         push    %edi
350
351         call    EXT(prot_to_real)       /* enter real mode */
352
353         xor     %ebx, %ebx
354         .code16
355         movb    $0x1, %ah
356         int     $0x18
357         andb    %bh, %bh
358         data32
359         jz      nochar
360         movb    %al, %bl
361
362 nochar:
363         .code32
364         data32
365         call    EXT(real_to_prot)
366
367         xor     %eax, %eax
368         movb    %bl, %al
369
370         pop     %edi
371         pop     %esi
372         pop     %ebx
373         pop     %ebp
374         ret
375
376 /*
377  *
378  * get_diskinfo():  return a word that represents the
379  *      max number of sectors and heads and drives for this device
380  *
381  */
382
383 ENTRY(get_diskinfo)
384         .code32
385         push    %ebp
386         mov     %esp, %ebp
387         push    %ebx
388
389         mov     0x08(%ebp), %bl         /* (byte) DA/UA */
390
391         call    EXT(prot_to_real)       /* enter real mode */
392         .code16
393         mov     %bl, %al                /* DA */
394         and     $0xf0, %al
395         mov     $18, %dl                /* 1440KB FD sectors per track */
396         cmp     $0x30, %al
397         jz      floppy
398         mov     $15, %dl                /* 1200KB FD sectors per track */
399         cmp     $0x90, %al
400         jz      floppy
401         cmp     $0xA0, %al              /* SCSI HD or MO */
402         jnz     sense
403         call    scsi_hd
404         jnz     sense
405
406         push    %ds                     /* SCSI MO or CD ? */
407         xor     %ax, %ax
408         mov     %ax, %ds
409         and     $0x0F, %bx              /* UA */
410         shl     $2, %bx                 /* parameter offset */
411         add     $0x0460, %bx
412         mov     (%bx), %al              /* SCSI equipment parameter[0] */
413         and     $0x1F, %al              /* peripheral device type */
414         cmp     $7, %al                 /* SCSI MO */
415         jnz     good
416         add     $3, %bx
417         mov     (%bx), %al              /* SCSI equipment parameter[3] */
418         test    $0x30, %al              /* sector length from 256 to 2048 */
419         jnz     good
420         or      $0x10, %al              /* forced set 512 bytes sector */
421         mov     %al, (%bx)
422         mov     $0xA100, %dx            /* refered by C language */
423         mov     %dx, %ds
424         mov     %al, (%bx)
425 good:
426         pop     %ds
427
428         mov     $0xFFFE, %cx            /* virtual 65535 cylinders setting */
429         mov     $0x0820, %dx            /* standard 8 heads and 32 sectors */
430         jmp     ok
431 sense:
432         mov     $0x84, %ah              /* ask for disk info */
433         mov     %bl, %al
434         int     $0x1b
435         jnc     ok                      /* use %cx and %dx after */
436         /*
437          * Urk.  Call failed.  It is not supported for floppies by old BIOS's.
438          * Guess it's a 15-sector floppy.
439          */
440 floppy:
441         mov     $79, %cx                /* 80 cylinders 1200K and 1440K FD */
442         mov     $2, %dh                 /* 2 heads as double side */
443 ok:
444         .code32
445         data32
446         call    EXT(real_to_prot)       /* back to protected mode */
447
448         /* 
449          * form a longword representing all this gunk:
450          *      16 bit cylinder
451          *       8 bit head
452          *       8 bit sector
453          */
454         mov     %ecx, %eax
455         sal     $16, %eax               /* max cylinder number from zero */
456         mov     %dx, %ax                /* number of heads and sectors */
457
458         pop     %ebx
459         pop     %ebp
460         ret
461
462 /*
463  *
464  * memsize(i) :  return the memory size in KB. i == 0 for conventional memory,
465  *              i == 1 for extended memory
466  *              Both have the return value in AX.
467  *
468  */
469
470 ENTRY(memsize)
471         .code32
472         push    %ebp
473         mov     %esp, %ebp
474         push    %ebx
475         push    %esi
476         push    %edi
477
478         mov     8(%ebp), %ebx
479
480         xor     %eax, %eax
481         cmpb    $0x01, %bl
482         jnz     memcnv
483 memext:
484         movb    0xA1401 - BOOTSEG * 0x10, %al
485         shll    $7, %eax
486         xorl    %ebx, %ebx
487         movw    0xA1594 - BOOTSEG * 0x10, %bx
488         shll    $10, %ebx
489         addl    %ebx, %eax
490         jmp     xdone
491
492 memcnv:
493         movb    0xA1501 - BOOTSEG * 0x10, %al
494         andb    $0x07, %al
495         incl    %eax
496         shll    $7, %eax
497
498 xdone:
499         pop     %edi
500         pop     %esi
501         pop     %ebx
502         pop     %ebp
503         ret