initial commit
[freebsd-arm:freebsd-arm.git] / boot / pc98 / boot2 / boot1.S
1 /*-
2  * Copyright (c) 2008-2009 TAKAHASHI Yoshihiro
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 /* Memory Locations */
30                 .set STACK_OFF,0x6000           # Stack offset
31                 .set LOAD_SIZE,8192             # Load size
32                 .set DAUA,0x0584                # DA/UA
33                 .set MEM_REL,0x700              # Relocation address
34                 .set MEM_ARG,0x900              # Arguments
35                 .set MEM_BUF,0x8cec             # Load area
36                 .set MEM_BTX,0x9000             # BTX start
37                 .set MEM_JMP,0x9010             # BTX entry point
38                 .set MEM_USR,0xa000             # Client start
39
40 /* PC98 machine type from sys/pc98/pc98/pc98_machdep.h */
41                 .set MEM_SYS,           0xa100  # System common area segment
42                 .set PC98_MACHINE_TYPE, 0x0620  # PC98 machine type
43                 .set EPSON_ID,          0x0624  # EPSON machine id
44
45                 .set M_NEC_PC98,        0x0001
46                 .set M_EPSON_PC98,      0x0002
47                 .set M_NOT_H98,         0x0010
48                 .set M_H98,             0x0020
49                 .set M_NOTE,            0x0040
50                 .set M_NORMAL,          0x1000
51                 .set M_8M,              0x8000
52
53 /* Partition Constants */
54                 .set PRT_OFF,0x1be              # Partition offset
55
56 /* Misc. Constants */
57                 .set SIZ_PAG,0x1000             # Page size
58                 .set SIZ_SEC,0x200              # Sector size
59
60                 .set NSECT,0x10
61
62                 .globl start
63                 .globl read
64                 .globl putc
65                 .code16
66
67 start:          jmp main
68
69 boot_cyl:       .org 4
70                 .ascii "IPL1   "
71
72 main:           cld
73
74                 /* Setup the stack */
75                 xor %si,%si
76                 mov %si,%ss
77                 mov $STACK_OFF,%sp
78
79                 push %cx
80
81                 /* Relocate ourself to MEM_REL */
82                 push %cs
83                 pop %ds
84                 mov %si,%es
85                 mov $MEM_REL,%di
86                 mov $SIZ_SEC,%cx
87                 rep
88                 movsb
89
90                 /* Transfer PC-9801 system common area */
91                 xor %ax,%ax
92                 mov %ax,%si
93                 mov %ax,%ds
94                 mov %ax,%di
95                 mov $MEM_SYS,%ax
96                 mov %ax,%es
97                 mov $0x0600,%cx
98                 rep
99                 movsb
100
101                 /* Transfer EPSON machine type */
102                 mov $0xfd00,%ax
103                 mov %ax,%ds
104                 mov (0x804),%eax
105                 and $0x00ffffff,%eax
106                 mov %eax,%es:(EPSON_ID)
107
108                 /* Set machine type to PC98_SYSTEM_PARAMETER */
109 #ifdef SET_MACHINE_TYPE
110                 call set_machine_type
111 #else
112                 mov $M_NEC_PC98+M_NOT_H98,%eax
113                 mov %eax,%es:(PC98_MACHINE_TYPE)
114 #endif
115
116                 /* Setup graphic screen */
117                 mov $0x42,%ah           /* 640x400 */
118                 mov $0xc0,%ch
119                 int $0x18
120                 mov $0x40,%ah           /* graph on */
121                 int $0x18
122
123                 /* Setup text screen */
124                 mov $0x0a00,%ax         /* 80x25 */
125                 int $0x18
126                 mov $0x0c,%ah           /* text on */
127                 int $0x18
128                 mov $0x13,%ah           /* cursor home */
129                 xor %dx,%dx
130                 int $0x18
131                 mov $0x11,%ah           /* cursor on */
132                 int $0x18
133
134                 /* Setup keyboard */
135                 mov $0x03,%ah
136                 int $0x18
137
138                 pop %cx
139
140                 /* bootstrap passes */
141                 xor %edi,%edi
142                 mov %di,%ds
143                 mov %di,%es
144                 mov %cs,%bx
145                 cmp $0x1fe0,%bx
146                 jz boot_fd
147                 cmp $0x1fc0,%bx
148                 jnz boot_hd
149                 xor %cx,%cx
150                 mov (DAUA),%al
151                 and $0xf0,%al
152                 cmp $0x30,%al
153                 jz boot_fd
154                 cmp $0x90,%al
155                 jnz boot_hd
156 boot_fd:        xor %cx,%cx
157                 jmp boot_load
158 boot_hd:        test %cx,%cx
159                 jnz boot_load
160                 mov %cs:(boot_cyl),%cx
161 boot_load:      mov %cx,MEM_ARG         /* Save cylinder number */
162                 mov %cx,%di
163                 xor %dx,%dx
164                 mov $LOAD_SIZE,%bx
165                 mov $MEM_BUF,%bp
166                 push %cs
167                 callw read
168                 jc error
169
170                 /* Transfer boot2.bin */
171                 mov $MEM_BTX,%bx
172                 mov 0xa(%bx),%si        /* BTX size */
173                 add %bx,%si             /* start of boot2.bin */
174                 mov $MEM_USR+SIZ_PAG*2,%di
175                 mov $MEM_BTX+(NSECT-1)*SIZ_SEC,%cx
176                 sub %si,%cx
177                 rep
178                 movsb
179
180                 /* Enable A20 */
181                 xor %ax,%ax
182                 outb %al,$0xf2
183                 mov $0x02,%al
184                 outb %al,$0xf6
185
186                 /* Start BTX */
187                 ljmp $0x0000,$MEM_JMP
188
189 /*
190  * Reads sectors from the disk.
191  * Call with:
192  *
193  * %bx          - bytes to read
194  * %cx          - cylinder
195  * %dh          - head
196  * %dl          - sector
197  * %edi         - lba
198  * %es:(%bp)    - buffer to read data into
199  */
200 read:           xor %ax,%ax
201                 mov %ax,%ds
202                 mov $0x06,%ah
203                 mov (DAUA),%al
204                 mov %ax,%si
205                 and $0xf0,%al
206                 cmp $0x30,%al           /* 1.44MB FDD */
207                 jz read_fd
208                 cmp $0x90,%al           /* 1MB FDD */
209                 jz read_fd
210                 cmp $0xa0,%al           /* Is SCSI device? */
211                 jnz read_load
212                 push %cx
213                 mov %si,%cx
214                 and $0x0f,%cl
215                 inc %cl
216                 mov (0x482),%ah
217                 shr %cl,%ah             /* Is SCSI HDD? */
218                 pop %cx
219                 jc read_load
220                 and $0xff7f,%si         /* SCSI MO */
221                 mov %di,%cx
222                 shr $16,%di
223                 mov %di,%dx
224                 jmp read_load
225 read_fd:        or $0xd000,%si
226                 or $0x0200,%cx
227                 inc %dx
228 read_load:      mov %si,%ax
229                 int $0x1b
230                 lret
231
232 /*
233  * Print out the error message, wait for a keypress, and then reboot
234  * the machine.
235  */
236 error:          push %cs
237                 pop %ds
238                 mov $msg_eread,%si
239                 call putstr
240                 xor %ax,%ax             /* Get keypress */
241                 int $0x18
242                 xor %ax,%ax             /* CPU reset */
243                 outb %al,$0xf0
244 halt:           hlt
245                 jmp halt                /* Spin */
246
247 /*
248  * Display a null-terminated string.
249  */
250 putstr.0:       push %cs
251                 callw putc
252 putstr:         lodsb
253                 test %al,%al
254                 jne putstr.0
255                 ret
256
257 /*
258  * Display a single char.
259  */
260 putc:           pusha
261                 xor %dx,%dx
262                 mov %dx,%ds
263                 mov MEM_REL+cursor-start,%di
264                 mov $0xa000,%bx
265                 mov %bx,%es
266                 mov $(80*2),%cx
267
268                 cmp $0x08,%al
269                 je putc.bs
270                 cmp $0x0d,%al
271                 je putc.cr
272                 cmp $0x0a,%al
273                 je putc.lf
274                 cmp $0x5c,%al                   /* \ */
275                 jne 1f
276                 mov $0xfc,%al
277 1:              movb $0xe1,%es:0x2000(%di)
278                 stosw
279                 jmp putc.scr
280 putc.bs:        test %di,%di
281                 jz putc.move
282                 dec %di
283                 dec %di
284                 movb $0xe1,%es:0x2000(%di)
285                 movw $0x20,%es:(%di)
286                 jmp putc.move
287 putc.cr:        mov %di,%ax
288                 div %cx
289                 sub %dx,%di
290                 jmp putc.move
291 putc.lf:        add %cx,%di
292 putc.scr:       cmp $(80*2*25),%di              /* Scroll screen */
293                 jb putc.move
294                 push %ds
295                 mov %bx,%ds
296                 mov $(80*2),%si
297                 xor %di,%di
298                 mov $(80*24/2),%cx
299                 rep
300                 movsl
301                 xor %ax,%ax
302                 mov $0x20,%al
303                 mov $80,%cl
304                 rep
305                 stosw
306                 pop %ds
307                 mov $(80*24*2),%di
308 putc.move:      mov %di,MEM_REL+cursor-start    /* Move cursor */
309                 mov $0x13,%ah
310                 mov %di,%dx
311                 int $0x18
312                 popa
313                 lret
314
315 cursor:         .word 0
316
317 #ifdef SET_MACHINE_TYPE
318 /*
319  * Set machine type to PC98_SYSTEM_PARAMETER.
320  */
321 set_machine_type:
322                 xor %edx,%edx
323                 mov %dx,%ds
324 //              mov $MEM_SYS,%ax
325 //              mov %ax,%es
326
327                 /* Wait V-SYNC */
328 vsync.1:        inb $0x60,%al
329                 test $0x20,%al
330                 jnz vsync.1
331 vsync.2:        inb $0x60,%al
332                 test $0x20,%al
333                 jz vsync.2
334
335                 /* ANK 'A' font */
336                 xor %al,%al
337                 outb %al,$0xa1
338                 mov $0x41,%al
339                 outb %al,$0xa3
340
341                 /* Get 'A' font from CG window */
342                 push %ds
343                 mov $0xa400,%ax
344                 mov %ax,%ds
345                 xor %eax,%eax
346                 xor %bx,%bx
347                 mov $4,%cx
348 font.1:         add (%bx),%eax
349                 add $4,%bx
350                 loop font.1
351                 pop %ds
352                 cmp $0x6efc58fc,%eax
353                 jnz m_epson
354
355 m_pc98:         or $M_NEC_PC98,%edx
356                 mov $0x0458,%bx
357                 mov (%bx),%al
358                 test $0x80,%al
359                 jz m_not_h98
360                 or $M_H98,%edx
361                 jmp 1f
362 m_epson:        or $M_EPSON_PC98,%edx
363 m_not_h98:      or $M_NOT_H98,%edx
364
365 1:              inb $0x42,%al
366                 test $0x20,%al
367                 jz 1f
368                 or $M_8M,%edx
369
370 1:              mov $0x0400,%bx
371                 mov (%bx),%al
372                 test $0x80,%al
373                 jz 1f
374                 or $M_NOTE,%edx
375
376 1:              mov $PC98_MACHINE_TYPE,%bx
377                 mov %edx,%es:(%bx)
378                 ret
379 #endif
380
381 /* Messages */
382
383 msg_eread:      .asciz "Error\r\n"
384
385                 .org PRT_OFF,0x90
386
387 /* Partition table */
388
389                 .fill 0x30,0x1,0x0
390                 .byte 0x80, 0x00, 0x01, 0x00
391                 .byte 0xa5, 0xff, 0xff, 0xff
392                 .byte 0x00, 0x00, 0x00, 0x00
393                 .byte 0x50, 0xc3, 0x00, 0x00
394
395                 .word 0xaa55                    # Magic number