1201342Snyan/*- 2201342Snyan * Copyright (c) 2008-2009 TAKAHASHI Yoshihiro 3201342Snyan * All rights reserved. 4201342Snyan * 5201342Snyan * Redistribution and use in source and binary forms, with or without 6201342Snyan * modification, are permitted provided that the following conditions 7201342Snyan * are met: 8201342Snyan * 1. Redistributions of source code must retain the above copyright 9201342Snyan * notice, this list of conditions and the following disclaimer. 10201342Snyan * 2. Redistributions in binary form must reproduce the above copyright 11201342Snyan * notice, this list of conditions and the following disclaimer in the 12201342Snyan * documentation and/or other materials provided with the distribution. 13201342Snyan * 14201342Snyan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15201342Snyan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16201342Snyan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17201342Snyan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18201342Snyan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19201342Snyan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20201342Snyan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21201342Snyan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22201342Snyan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23201342Snyan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24201342Snyan * SUCH DAMAGE. 25201342Snyan * 26201342Snyan * $FreeBSD: stable/11/stand/pc98/boot2/boot1.S 229462 2012-01-04 03:49:41Z nyan $ 27201342Snyan */ 28201342Snyan 29201342Snyan/* Memory Locations */ 30201342Snyan .set STACK_OFF,0x6000 # Stack offset 31201342Snyan .set LOAD_SIZE,8192 # Load size 32201342Snyan .set DAUA,0x0584 # DA/UA 33201342Snyan .set MEM_REL,0x700 # Relocation address 34201342Snyan .set MEM_ARG,0x900 # Arguments 35201342Snyan .set MEM_BUF,0x8cec # Load area 36201342Snyan .set MEM_BTX,0x9000 # BTX start 37201342Snyan .set MEM_JMP,0x9010 # BTX entry point 38201342Snyan .set MEM_USR,0xa000 # Client start 39201342Snyan 40201342Snyan/* PC98 machine type from sys/pc98/pc98/pc98_machdep.h */ 41201342Snyan .set MEM_SYS, 0xa100 # System common area segment 42201342Snyan .set PC98_MACHINE_TYPE, 0x0620 # PC98 machine type 43201342Snyan .set EPSON_ID, 0x0624 # EPSON machine id 44201342Snyan 45201342Snyan .set M_NEC_PC98, 0x0001 46201342Snyan .set M_EPSON_PC98, 0x0002 47201342Snyan .set M_NOT_H98, 0x0010 48201342Snyan .set M_H98, 0x0020 49201342Snyan .set M_NOTE, 0x0040 50201342Snyan .set M_NORMAL, 0x1000 51201342Snyan .set M_8M, 0x8000 52201342Snyan 53201342Snyan/* Partition Constants */ 54201342Snyan .set PRT_OFF,0x1be # Partition offset 55201342Snyan 56201342Snyan/* Misc. Constants */ 57201342Snyan .set SIZ_PAG,0x1000 # Page size 58201342Snyan .set SIZ_SEC,0x200 # Sector size 59201342Snyan 60201342Snyan .set NSECT,0x10 61201342Snyan 62201342Snyan .globl start 63201342Snyan .globl read 64201342Snyan .globl putc 65201342Snyan .code16 66201342Snyan 67201342Snyanstart: jmp main 68201342Snyan 69201342Snyanboot_cyl: .org 4 70201342Snyan .ascii "IPL1 " 71201342Snyan 72201342Snyanmain: cld 73201342Snyan 74201342Snyan /* Setup the stack */ 75201342Snyan xor %si,%si 76201342Snyan mov %si,%ss 77201342Snyan mov $STACK_OFF,%sp 78201342Snyan 79201342Snyan push %cx 80201342Snyan 81201342Snyan /* Relocate ourself to MEM_REL */ 82201342Snyan push %cs 83201342Snyan pop %ds 84201342Snyan mov %si,%es 85201342Snyan mov $MEM_REL,%di 86201342Snyan mov $SIZ_SEC,%cx 87201342Snyan rep 88201342Snyan movsb 89201342Snyan 90201342Snyan /* Transfer PC-9801 system common area */ 91201342Snyan xor %ax,%ax 92201342Snyan mov %ax,%si 93201342Snyan mov %ax,%ds 94201342Snyan mov %ax,%di 95201342Snyan mov $MEM_SYS,%ax 96201342Snyan mov %ax,%es 97201342Snyan mov $0x0600,%cx 98201342Snyan rep 99201342Snyan movsb 100201342Snyan 101201342Snyan /* Transfer EPSON machine type */ 102201342Snyan mov $0xfd00,%ax 103201342Snyan mov %ax,%ds 104201342Snyan mov (0x804),%eax 105201342Snyan and $0x00ffffff,%eax 106201342Snyan mov %eax,%es:(EPSON_ID) 107201342Snyan 108201342Snyan /* Set machine type to PC98_SYSTEM_PARAMETER */ 109201342Snyan#ifdef SET_MACHINE_TYPE 110201342Snyan call set_machine_type 111201342Snyan#else 112201342Snyan mov $M_NEC_PC98+M_NOT_H98,%eax 113201342Snyan mov %eax,%es:(PC98_MACHINE_TYPE) 114201342Snyan#endif 115201342Snyan 116201342Snyan /* Setup graphic screen */ 117201342Snyan mov $0x42,%ah /* 640x400 */ 118201342Snyan mov $0xc0,%ch 119201342Snyan int $0x18 120201342Snyan mov $0x40,%ah /* graph on */ 121201342Snyan int $0x18 122201342Snyan 123201342Snyan /* Setup text screen */ 124201342Snyan mov $0x0a00,%ax /* 80x25 */ 125201342Snyan int $0x18 126201342Snyan mov $0x0c,%ah /* text on */ 127201342Snyan int $0x18 128201342Snyan mov $0x13,%ah /* cursor home */ 129201342Snyan xor %dx,%dx 130201342Snyan int $0x18 131201342Snyan mov $0x11,%ah /* cursor on */ 132201342Snyan int $0x18 133201342Snyan 134201342Snyan /* Setup keyboard */ 135201342Snyan mov $0x03,%ah 136201342Snyan int $0x18 137201342Snyan 138201342Snyan pop %cx 139201342Snyan 140201342Snyan /* bootstrap passes */ 141201342Snyan xor %edi,%edi 142201342Snyan mov %di,%ds 143201342Snyan mov %di,%es 144201342Snyan mov %cs,%bx 145201342Snyan cmp $0x1fe0,%bx 146201342Snyan jz boot_fd 147201342Snyan cmp $0x1fc0,%bx 148201342Snyan jnz boot_hd 149201342Snyan xor %cx,%cx 150201342Snyan mov (DAUA),%al 151201342Snyan and $0xf0,%al 152201342Snyan cmp $0x30,%al 153201342Snyan jz boot_fd 154201342Snyan cmp $0x90,%al 155201342Snyan jnz boot_hd 156201342Snyanboot_fd: xor %cx,%cx 157201342Snyan jmp boot_load 158201342Snyanboot_hd: test %cx,%cx 159201342Snyan jnz boot_load 160201342Snyan mov %cs:(boot_cyl),%cx 161201342Snyanboot_load: mov %cx,MEM_ARG /* Save cylinder number */ 162201342Snyan mov %cx,%di 163201342Snyan xor %dx,%dx 164201342Snyan mov $LOAD_SIZE,%bx 165201342Snyan mov $MEM_BUF,%bp 166201342Snyan push %cs 167201342Snyan callw read 168201342Snyan jc error 169201342Snyan 170201342Snyan /* Transfer boot2.bin */ 171201342Snyan mov $MEM_BTX,%bx 172201342Snyan mov 0xa(%bx),%si /* BTX size */ 173201342Snyan add %bx,%si /* start of boot2.bin */ 174201342Snyan mov $MEM_USR+SIZ_PAG*2,%di 175201342Snyan mov $MEM_BTX+(NSECT-1)*SIZ_SEC,%cx 176201342Snyan sub %si,%cx 177201342Snyan rep 178201342Snyan movsb 179201342Snyan 180201342Snyan /* Enable A20 */ 181201342Snyan xor %ax,%ax 182201342Snyan outb %al,$0xf2 183201342Snyan mov $0x02,%al 184201342Snyan outb %al,$0xf6 185201342Snyan 186201342Snyan /* Start BTX */ 187201342Snyan ljmp $0x0000,$MEM_JMP 188201342Snyan 189201342Snyan/* 190201342Snyan * Reads sectors from the disk. 191201342Snyan * Call with: 192201342Snyan * 193201342Snyan * %bx - bytes to read 194201342Snyan * %cx - cylinder 195201342Snyan * %dh - head 196201342Snyan * %dl - sector 197201342Snyan * %edi - lba 198201342Snyan * %es:(%bp) - buffer to read data into 199201342Snyan */ 200201342Snyanread: xor %ax,%ax 201201342Snyan mov %ax,%ds 202201342Snyan mov $0x06,%ah 203201342Snyan mov (DAUA),%al 204201342Snyan mov %ax,%si 205201342Snyan and $0xf0,%al 206201342Snyan cmp $0x30,%al /* 1.44MB FDD */ 207201342Snyan jz read_fd 208201342Snyan cmp $0x90,%al /* 1MB FDD */ 209201342Snyan jz read_fd 210201342Snyan cmp $0xa0,%al /* Is SCSI device? */ 211201342Snyan jnz read_load 212201342Snyan push %cx 213201342Snyan mov %si,%cx 214201342Snyan and $0x0f,%cl 215201342Snyan inc %cl 216201342Snyan mov (0x482),%ah 217201342Snyan shr %cl,%ah /* Is SCSI HDD? */ 218201342Snyan pop %cx 219201342Snyan jc read_load 220201342Snyan and $0xff7f,%si /* SCSI MO */ 221201342Snyan mov %di,%cx 222229462Snyan shr $16,%edi 223201342Snyan mov %di,%dx 224201342Snyan jmp read_load 225201342Snyanread_fd: or $0xd000,%si 226201342Snyan or $0x0200,%cx 227201342Snyan inc %dx 228201342Snyanread_load: mov %si,%ax 229201342Snyan int $0x1b 230201342Snyan lret 231201342Snyan 232201342Snyan/* 233201342Snyan * Print out the error message, wait for a keypress, and then reboot 234201342Snyan * the machine. 235201342Snyan */ 236201342Snyanerror: push %cs 237201342Snyan pop %ds 238201342Snyan mov $msg_eread,%si 239201342Snyan call putstr 240201342Snyan xor %ax,%ax /* Get keypress */ 241201342Snyan int $0x18 242201342Snyan xor %ax,%ax /* CPU reset */ 243201342Snyan outb %al,$0xf0 244201342Snyanhalt: hlt 245201342Snyan jmp halt /* Spin */ 246201342Snyan 247201342Snyan/* 248201342Snyan * Display a null-terminated string. 249201342Snyan */ 250201342Snyanputstr.0: push %cs 251201342Snyan callw putc 252201342Snyanputstr: lodsb 253201342Snyan test %al,%al 254201342Snyan jne putstr.0 255201342Snyan ret 256201342Snyan 257201342Snyan/* 258201342Snyan * Display a single char. 259201342Snyan */ 260201342Snyanputc: pusha 261201342Snyan xor %dx,%dx 262201342Snyan mov %dx,%ds 263201342Snyan mov MEM_REL+cursor-start,%di 264201342Snyan mov $0xa000,%bx 265201342Snyan mov %bx,%es 266201342Snyan mov $(80*2),%cx 267201342Snyan 268201342Snyan cmp $0x08,%al 269201342Snyan je putc.bs 270201342Snyan cmp $0x0d,%al 271201342Snyan je putc.cr 272201342Snyan cmp $0x0a,%al 273201342Snyan je putc.lf 274201342Snyan cmp $0x5c,%al /* \ */ 275201342Snyan jne 1f 276201342Snyan mov $0xfc,%al 277201342Snyan1: movb $0xe1,%es:0x2000(%di) 278201342Snyan stosw 279201342Snyan jmp putc.scr 280201342Snyanputc.bs: test %di,%di 281201342Snyan jz putc.move 282201342Snyan dec %di 283201342Snyan dec %di 284201342Snyan movb $0xe1,%es:0x2000(%di) 285201342Snyan movw $0x20,%es:(%di) 286201342Snyan jmp putc.move 287201342Snyanputc.cr: mov %di,%ax 288201342Snyan div %cx 289201342Snyan sub %dx,%di 290201342Snyan jmp putc.move 291201342Snyanputc.lf: add %cx,%di 292201342Snyanputc.scr: cmp $(80*2*25),%di /* Scroll screen */ 293201342Snyan jb putc.move 294201342Snyan push %ds 295201342Snyan mov %bx,%ds 296201342Snyan mov $(80*2),%si 297201342Snyan xor %di,%di 298201342Snyan mov $(80*24/2),%cx 299201342Snyan rep 300201342Snyan movsl 301201342Snyan xor %ax,%ax 302201342Snyan mov $0x20,%al 303201342Snyan mov $80,%cl 304201342Snyan rep 305201342Snyan stosw 306201342Snyan pop %ds 307201342Snyan mov $(80*24*2),%di 308201342Snyanputc.move: mov %di,MEM_REL+cursor-start /* Move cursor */ 309201342Snyan mov $0x13,%ah 310201342Snyan mov %di,%dx 311201342Snyan int $0x18 312201342Snyan popa 313201342Snyan lret 314201342Snyan 315201342Snyancursor: .word 0 316201342Snyan 317201342Snyan#ifdef SET_MACHINE_TYPE 318201342Snyan/* 319201342Snyan * Set machine type to PC98_SYSTEM_PARAMETER. 320201342Snyan */ 321201342Snyanset_machine_type: 322201342Snyan xor %edx,%edx 323201342Snyan mov %dx,%ds 324201342Snyan// mov $MEM_SYS,%ax 325201342Snyan// mov %ax,%es 326201342Snyan 327201342Snyan /* Wait V-SYNC */ 328201342Snyanvsync.1: inb $0x60,%al 329201342Snyan test $0x20,%al 330201342Snyan jnz vsync.1 331201342Snyanvsync.2: inb $0x60,%al 332201342Snyan test $0x20,%al 333201342Snyan jz vsync.2 334201342Snyan 335201342Snyan /* ANK 'A' font */ 336201342Snyan xor %al,%al 337201342Snyan outb %al,$0xa1 338201342Snyan mov $0x41,%al 339201342Snyan outb %al,$0xa3 340201342Snyan 341201342Snyan /* Get 'A' font from CG window */ 342201342Snyan push %ds 343201342Snyan mov $0xa400,%ax 344201342Snyan mov %ax,%ds 345201342Snyan xor %eax,%eax 346201342Snyan xor %bx,%bx 347201342Snyan mov $4,%cx 348201342Snyanfont.1: add (%bx),%eax 349201342Snyan add $4,%bx 350201342Snyan loop font.1 351201342Snyan pop %ds 352201342Snyan cmp $0x6efc58fc,%eax 353201342Snyan jnz m_epson 354201342Snyan 355201342Snyanm_pc98: or $M_NEC_PC98,%edx 356201342Snyan mov $0x0458,%bx 357201342Snyan mov (%bx),%al 358201342Snyan test $0x80,%al 359201342Snyan jz m_not_h98 360201342Snyan or $M_H98,%edx 361201342Snyan jmp 1f 362201342Snyanm_epson: or $M_EPSON_PC98,%edx 363201342Snyanm_not_h98: or $M_NOT_H98,%edx 364201342Snyan 365201342Snyan1: inb $0x42,%al 366201342Snyan test $0x20,%al 367201342Snyan jz 1f 368201342Snyan or $M_8M,%edx 369201342Snyan 370201342Snyan1: mov $0x0400,%bx 371201342Snyan mov (%bx),%al 372201342Snyan test $0x80,%al 373201342Snyan jz 1f 374201342Snyan or $M_NOTE,%edx 375201342Snyan 376201342Snyan1: mov $PC98_MACHINE_TYPE,%bx 377201342Snyan mov %edx,%es:(%bx) 378201342Snyan ret 379201342Snyan#endif 380201342Snyan 381201342Snyan/* Messages */ 382201342Snyan 383201342Snyanmsg_eread: .asciz "Error\r\n" 384201342Snyan 385201342Snyan .org PRT_OFF,0x90 386201342Snyan 387201342Snyan/* Partition table */ 388201342Snyan 389201342Snyan .fill 0x30,0x1,0x0 390201342Snyan .byte 0x80, 0x00, 0x01, 0x00 391201342Snyan .byte 0xa5, 0xff, 0xff, 0xff 392201342Snyan .byte 0x00, 0x00, 0x00, 0x00 393201342Snyan .byte 0x50, 0xc3, 0x00, 0x00 394201342Snyan 395201342Snyan .word 0xaa55 # Magic number 396