]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/boot/pc98/boot2/start.S
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / sys / boot / pc98 / boot2 / start.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:36:29  rpd
27  * $FreeBSD$
28  */
29
30 /*
31   Copyright 1988, 1989, 1990, 1991, 1992 
32    by Intel Corporation, Santa Clara, California.
33
34                 All Rights Reserved
35
36 Permission to use, copy, modify, and distribute this software and
37 its documentation for any purpose and without fee is hereby
38 granted, provided that the above copyright notice appears in all
39 copies and that both the copyright notice and this permission notice
40 appear in supporting documentation, and that the name of Intel
41 not be used in advertising or publicity pertaining to distribution
42 of the software without specific, written prior permission.
43
44 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
45 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
46 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
47 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
48 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
49 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
50 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51 */
52 /*
53  * Ported to PC-9801 by Yoshio Kimura
54  */
55
56 #include        "asm.h"
57
58         .file   "start.S"
59
60 SIGNATURE=      0xaa55
61 LOADSZ=         8192    /* size of unix boot */
62
63 NAMEBLOCKMAGIC= 0xfadefeed /* value of magicnumebr for block2   */
64
65 /*
66  * This DEBUGMSG(msg) macro may be useful for debugging.  Its use is
67  * restricted to this file since it only works in real mode.
68  */
69 #define DEBUGMSG(msg)           \
70         data32                  ; \
71         mov     $msg, %esi      ; \
72         data32                  ; \
73         call    message
74
75         .text   
76         .globl  start
77
78 ENTRY(boot1)
79         jmp     start
80
81 boot_cyl:
82         .word   0
83         String  "IPL1   "
84
85 start:
86         /* set up %ds */
87         xor     %ax, %ax
88         mov     %ax, %ds
89
90         /* set up %ss and %esp */
91         data32
92         mov     $BOOTSEG, %eax
93         mov     %ax, %ss
94         /*
95          * make a little room on the stack for
96          * us to save the default bootstring we might find..
97          * effectively, we push the bootstring.
98          */
99         data32
100         mov     $BOOTSTACK-64, %esp
101
102         /* set up %es, (where we will load boot2 to) */
103         mov     %ax, %es
104
105         push    %es
106         push    %cx
107         push    %dx
108
109         data32
110         mov     $0xa000, %eax
111         mov     %ax, %es
112
113         addr32
114         movb    0x501, %al
115         testb   $0x08, %al
116         jnz     hireso
117 normal:
118         /* set up graphic screen */
119         movb    $0x42, %ah
120         movb    $0xc0, %ch
121         int     $0x18
122         movb    $0x40, %ah
123         int     $0x18
124
125         data32
126         mov     $0x0a00, %eax           /* 80 x 25 mode  */
127         jmp     1f
128 hireso:
129         movb    $0x08, %al              /* set up RAM window */
130         outb    %al, $0x91
131         movb    $0x0a, %al
132         outb    %al, $0x93
133         data32
134         mov     $0x0a10, %ax            /* 80 x 31 mode */
135 1:
136         int     $0x18
137         movb    $0x0c, %ah              /* text on */
138         int     $0x18
139
140         /* cursor home and on */
141         xor     %edx, %edx
142         movb    $0x13, %ah
143         int     $0x18
144         movb    $0x11, %ah
145         int     $0x18
146
147         /* highreso no supported */
148         addr32
149         movb    0x501, %al
150         testb   $0x08, %al
151         jz      nothireso
152
153         data32
154         mov     $ehireso, %esi
155         data32
156         call    message
157         hlt
158
159 nothireso:
160         /* keyboad reset */
161         movb    $0x03, %ah
162         int     $0x18
163
164         /* transfer PC-9801 system common area to 0xa1000 */
165         data32
166         mov     $0x0000, %esi
167         data32
168         mov     $0x1000, %edi
169         data32
170         mov     $0x0630, %ecx
171         cld
172         rep
173         movsb
174
175         /* transfer EPSON machine type to 0xa1200 */
176         push    %ds
177         data32
178         mov     $0xfd00, %eax
179         mov     %ax, %ds
180         addr32
181         data32
182         mov     0x804, %eax
183         data32
184         and     $0x00ffffff, %eax
185         addr32
186         data32
187         .byte   0x26
188         mov     %eax, %es: (0x1624)
189
190         pop     %ds
191         pop     %dx
192         pop     %cx
193         pop     %es
194
195         /* bootstrap passes */
196         mov     %cs, %bx
197         data32
198         cmp     $0x1fe0, %ebx
199         jz      fd
200         data32
201         cmp     $0x1fc0, %ebx
202         jnz     hd
203         data32
204         mov     %ebp, %ecx
205         data32
206         mov     %ebp, %edx
207         addr32
208         movb    0x584, %al
209         andb    $0xf0, %al
210         cmpb    $0x30, %al
211         jz      fd
212         cmpb    $0x90, %al
213         jnz     hd
214 fd:
215         data32
216         mov     $0x0200, %ecx
217         data32
218         mov     $0x0001, %edx
219         movb    $0xd6, %ah
220         jmp     load
221 hd:
222         data32
223         and     %ecx, %ecx
224         jnz     1f
225         addr32
226         data32
227         mov     %cs: (boot_cyl), %ecx
228 1:
229         movb    $0x06, %ah      
230
231 /*
232  * BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory
233  *      Call with       %ah = 0xd6(for floppy disk) or 0x06(for hard disk)
234  *                      %al = DA/UA
235  *                      %bx = data length
236  *                      %ch = sector size(for floppy) or cylinder(for hard)
237  *                      %cl = cylinder
238  *                      %dh = head
239  *                      %dl = sector
240  *                      %es:%bp = segment:offset of buffer
241  *      Return:
242  *                      %ah = 0x0 on success; err code on failure
243  */
244
245 load:
246 #ifdef NAMEBLOCK
247 /*
248  * Load the second sector and see if it is a boot instruction block.
249  * If it is then scan the contents for the first valid string and copy it to 
250  * the location of the default boot string.. then zero it out.
251  * Finally write the block back to disk with the zero'd out entry..
252  * I hate writing at this stage but we need this to be persistant.
253  * If the boot fails, then the next boot will get the next string.
254  * /etc/rc will regenerate a complete block2 iff the boot succeeds.
255  *
256  * Format of block 2 is:
257  * [NAMEBLOCKMAGIC] <--0xdeafc0de
258  * [nulls]
259  * [bootstring]NULL  <---e.g. 0:wd(0,a)/kernel.experimental
260  * [bootstring]NULL  <---e.g. 0:wd(0,a)/kernel.old
261  * ....
262  * [bootstring]NULL  <---e.g. 0:wd(0,f)/kernel
263  * FF FF FF
264  */
265 where:
266         /*
267          * save things we might smash
268          * (that are not smashed immedatly after us anyway.)
269          */
270         data32
271         push    %ecx    /* preserve 'cyl,sector ' */
272         data32
273         push    %edx
274 /* 
275  * Load the second sector
276  * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
277  *      Call with       %ah = 0x2
278  *                      %al = number of sectors
279  *                      %ch = cylinder
280  *                      %cl = sector
281  *                      %dh = head
282  *                      %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
283  *                      %es:%bx = segment:offset of buffer
284  *      Return:
285  *                      %al = 0x0 on success; err code on failure
286  */
287         data32
288         movl    $0x0201, %eax   /function 2 (read) 1 sector */
289         xor     %ebx, %ebx      /* %bx = 0 */ /* buffer address (ES:0) */
290         data32
291         movl    $0x0002, %ecx   /* sector 2, cylinder 0 */
292         data32
293         andl    $0x00ff, %edx   /* head 0, drive N */
294         int     $0x13
295         data32
296         jb      read_error
297         /*
298          * confirm that it is one for us
299          */
300         data32
301         xorl    %ebx, %ebx      /* magic number at start of buffer */
302         data32
303         addr32
304         movl    %es:(%ebx), %eax
305         data32
306         cmpl    $NAMEBLOCKMAGIC, %eax
307         data32
308         jne     notours         /* not ours so return to caller */
309         /*
310          * scan for a bootstring
311          * Skip the magic number, and scan till we find a non-null,
312          * or a -1
313          */
314         incl    %ebx    /* quicker and smaller */
315         incl    %ebx
316         incl    %ebx
317 scan:
318         incl    %ebx
319         addr32
320         movb    %es:(%ebx), %al /* load the next byte */
321         testb   %al, %al        /* and if it is null */
322         data32                  /* keep scanning (past deleted entries) */
323         jz scan
324         incb    %al             /* now look for -1 */
325         data32
326         jz      notours         /* if we reach the 0xFF then we have finished */
327
328         /*
329          * save our settings.. we need them twice..
330          */
331         data32
332         push    %ebx
333         /*
334          * copy it to the default string location
335          * which is just above the stack for 64 bytes.
336          */
337         data32
338         movl    $BOOTSTACK-64, %ecx     /* 64 bytes at the top of the stack */
339 nxtbyte:
340         addr32
341         movb    %es:(%ebx), %al /* get the next byte in */
342         addr32
343         movb    %al, %es:(%ecx) /* and transfer it to the name buffer */
344         incl    %ebx            /* get on with the next byte */
345         incl    %ecx            /* get on with the next byte */
346         testb   %al, %al        /* if it was 0 then quit this */
347         data32
348         jnz nxtbyte             /* and looop if more to do */ 
349         
350         /*
351          * restore the saved settings and
352          * zero it out so next time we don't try it again
353          */
354         data32
355         pop     %ebx            /* get back our starting location */
356 #ifdef  NAMEBLOCK_WRITEBACK
357 nxtbyte2:
358         addr32
359         movb    %es:(%ebx), %al /* get the byte */
360         addr32
361         movb    $0,  %es:(%ebx) /* zero it out */
362         data32
363         incl    %ebx            /* point to the next byte */
364         testb   %al, %al        /* check if we have finished.. */
365         data32
366         jne nxtbyte2
367 /* 
368  * Write the second sector back
369  * Load the second sector
370  * BIOS call "INT 0x13 Function 0x3" to write sectors from memory to disk
371  *      Call with       %ah = 0x3
372  *                      %al = number of sectors
373  *                      %ch = cylinder
374  *                      %cl = sector
375  *                      %dh = head
376  *                      %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
377  *                      %es:%bx = segment:offset of buffer
378  *      Return:
379  *                      %al = 0x0 on success; err code on failure
380  */
381         data32
382         movl    $0x0301, %eax   /* write 1 sector */
383         xor     %ebx, %ebx      /* buffer is at offset 0 */ 
384         data32
385         movl    $0x0002, %ecx   /* block 2 */
386         data32
387         andl    $0xff, %edx     /* head 0 */
388         int     $0x13
389         data32
390         jnb     notours
391         data32
392         mov     $eread, %esi
393         jmp     err_stop
394 #endif  /* NAMEBLOCK_WRITEBACK */
395         /*
396          * return to the main-line
397          */
398 notours:
399         data32
400         pop     %edx
401         data32
402         pop     %ecx
403 #endif
404         data32
405         mov     $LOADSZ, %ebx
406         addr32
407         movb    0x584, %al
408         xor     %ebp, %ebp      /* %bp = 0, put it at 0 in the BOOTSEG */
409         int     $0x1b
410         jc      read_error
411
412         /*
413          * ljmp to the second stage boot loader (boot2).
414          * After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
415          * as an internal buffer "intbuf".
416          */
417
418         data32
419         ljmp    $BOOTSEG, $ EXT(boot2)
420
421 /*
422  * read_error
423  */
424 read_error:
425         data32
426         mov     $eread, %esi
427 err_stop:
428         data32
429         call    message
430         data32
431         jmp     stop
432
433 /*
434  * message: write the error message in %ds:%esi to console
435  */
436 message:
437
438         data32
439         push    %eax
440         data32
441         push    %ebx
442         push    %ds
443         push    %es
444         data32
445         mov     $0xe000, %eax
446         mov     %ax, %es
447         addr32
448         mov     0x501, %al
449         testb   $0x08, %al
450         jnz     1f
451         data32
452         mov     $0xa000, %eax
453         mov     %ax, %es
454 1:
455         mov     %cs, %ax
456         mov     %ax, %ds
457         addr32
458         data32
459         mov     vram, %edi
460         data32
461         mov     $0x00e1, %ebx
462         cld
463
464 nextb:
465         lodsb                   /* load a byte into %al */
466         cmpb    $0x0, %al
467         je      done
468         cmpb    $0x0d, %al
469         je      cr_code
470         cmpb    $0x0a, %al
471         je      lf_code
472         addr32
473         movb    %al, (%edi)
474         addr32
475         movb    %bl, 0x2000(%edi)
476         data32
477         inc     %edi
478         data32
479         inc     %edi
480         jmp     nextb
481 cr_code:
482         data32
483         add     $80, %edi
484         jmp     nextb
485 lf_code:
486         data32
487         mov     %edi, %eax
488         data32
489         mov     $80, %edx
490         data32
491         div     %ebx
492         data32
493         sub     %ebx, %edi
494         jmp     nextb
495 done:
496         addr32
497         data32
498         mov     %edi, vram
499         pop     %es
500         pop     %ds
501         data32
502         pop     %ebx
503         data32
504         pop     %eax
505         data32
506         ret
507
508 stop:   hlt
509         data32
510         jmp     stop            /* halt doesnt actually halt forever */
511
512 vram:
513         .long   0
514
515 /* error messages */
516
517
518 #ifdef  DEBUG
519 one:    String          "1-\0"
520 two:    String          "2-\0"
521 three:  String          "3-\0"
522 four:   String          "4-\0"
523 #endif  DEBUG
524 #ifdef  NAMEBLOCK_WRITEBACK
525 ewrite: String          "Write error\r\n\0"
526 #endif  /* NAMEBLOCK_WRITEBACK */
527 eread:  String          "Read error\r\n\0"
528 enoboot: String         "No bootable partition\r\n\0"
529 endofcode:
530 ehireso: String         "Highreso not supported\r\n\0"
531 /* the last 2 bytes in the sector 0 contain the signature */
532         . = EXT(boot1) + 0x1fe
533         .value  SIGNATURE
534 ENTRY(disklabel)
535         . = EXT(boot1) + 0x400