/*- * Copyright (c) 2008-2009 TAKAHASHI Yoshihiro * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* Memory Locations */ .set STACK_OFF,0x6000 # Stack offset .set LOAD_SIZE,8192 # Load size .set DAUA,0x0584 # DA/UA .set MEM_REL,0x700 # Relocation address .set MEM_ARG,0x900 # Arguments .set MEM_BUF,0x8cec # Load area .set MEM_BTX,0x9000 # BTX start .set MEM_JMP,0x9010 # BTX entry point .set MEM_USR,0xa000 # Client start /* PC98 machine type from sys/pc98/pc98/pc98_machdep.h */ .set MEM_SYS, 0xa100 # System common area segment .set PC98_MACHINE_TYPE, 0x0620 # PC98 machine type .set EPSON_ID, 0x0624 # EPSON machine id .set M_NEC_PC98, 0x0001 .set M_EPSON_PC98, 0x0002 .set M_NOT_H98, 0x0010 .set M_H98, 0x0020 .set M_NOTE, 0x0040 .set M_NORMAL, 0x1000 .set M_8M, 0x8000 /* Partition Constants */ .set PRT_OFF,0x1be # Partition offset /* Misc. Constants */ .set SIZ_PAG,0x1000 # Page size .set SIZ_SEC,0x200 # Sector size .set NSECT,0x10 .globl start .globl read .globl putc .code16 start: jmp main boot_cyl: .org 4 .ascii "IPL1 " main: cld /* Setup the stack */ xor %si,%si mov %si,%ss mov $STACK_OFF,%sp push %cx /* Relocate ourself to MEM_REL */ push %cs pop %ds mov %si,%es mov $MEM_REL,%di mov $SIZ_SEC,%cx rep movsb /* Transfer PC-9801 system common area */ xor %ax,%ax mov %ax,%si mov %ax,%ds mov %ax,%di mov $MEM_SYS,%ax mov %ax,%es mov $0x0600,%cx rep movsb /* Transfer EPSON machine type */ mov $0xfd00,%ax mov %ax,%ds mov (0x804),%eax and $0x00ffffff,%eax mov %eax,%es:(EPSON_ID) /* Set machine type to PC98_SYSTEM_PARAMETER */ #ifdef SET_MACHINE_TYPE call set_machine_type #else mov $M_NEC_PC98+M_NOT_H98,%eax mov %eax,%es:(PC98_MACHINE_TYPE) #endif /* Setup graphic screen */ mov $0x42,%ah /* 640x400 */ mov $0xc0,%ch int $0x18 mov $0x40,%ah /* graph on */ int $0x18 /* Setup text screen */ mov $0x0a00,%ax /* 80x25 */ int $0x18 mov $0x0c,%ah /* text on */ int $0x18 mov $0x13,%ah /* cursor home */ xor %dx,%dx int $0x18 mov $0x11,%ah /* cursor on */ int $0x18 /* Setup keyboard */ mov $0x03,%ah int $0x18 pop %cx /* bootstrap passes */ xor %edi,%edi mov %di,%ds mov %di,%es mov %cs,%bx cmp $0x1fe0,%bx jz boot_fd cmp $0x1fc0,%bx jnz boot_hd xor %cx,%cx mov (DAUA),%al and $0xf0,%al cmp $0x30,%al jz boot_fd cmp $0x90,%al jnz boot_hd boot_fd: xor %cx,%cx jmp boot_load boot_hd: test %cx,%cx jnz boot_load mov %cs:(boot_cyl),%cx boot_load: mov %cx,MEM_ARG /* Save cylinder number */ mov %cx,%di xor %dx,%dx mov $LOAD_SIZE,%bx mov $MEM_BUF,%bp push %cs callw read jc error /* Transfer boot2.bin */ mov $MEM_BTX,%bx mov 0xa(%bx),%si /* BTX size */ add %bx,%si /* start of boot2.bin */ mov $MEM_USR+SIZ_PAG*2,%di mov $MEM_BTX+(NSECT-1)*SIZ_SEC,%cx sub %si,%cx rep movsb /* Enable A20 */ xor %ax,%ax outb %al,$0xf2 mov $0x02,%al outb %al,$0xf6 /* Start BTX */ ljmp $0x0000,$MEM_JMP /* * Reads sectors from the disk. * Call with: * * %bx - bytes to read * %cx - cylinder * %dh - head * %dl - sector * %edi - lba * %es:(%bp) - buffer to read data into */ read: xor %ax,%ax mov %ax,%ds mov $0x06,%ah mov (DAUA),%al mov %ax,%si and $0xf0,%al cmp $0x30,%al /* 1.44MB FDD */ jz read_fd cmp $0x90,%al /* 1MB FDD */ jz read_fd cmp $0xa0,%al /* Is SCSI device? */ jnz read_load push %cx mov %si,%cx and $0x0f,%cl inc %cl mov (0x482),%ah shr %cl,%ah /* Is SCSI HDD? */ pop %cx jc read_load and $0xff7f,%si /* SCSI MO */ mov %di,%cx shr $16,%di mov %di,%dx jmp read_load read_fd: or $0xd000,%si or $0x0200,%cx inc %dx read_load: mov %si,%ax int $0x1b lret /* * Print out the error message, wait for a keypress, and then reboot * the machine. */ error: push %cs pop %ds mov $msg_eread,%si call putstr xor %ax,%ax /* Get keypress */ int $0x18 xor %ax,%ax /* CPU reset */ outb %al,$0xf0 halt: hlt jmp halt /* Spin */ /* * Display a null-terminated string. */ putstr.0: push %cs callw putc putstr: lodsb test %al,%al jne putstr.0 ret /* * Display a single char. */ putc: pusha xor %dx,%dx mov %dx,%ds mov MEM_REL+cursor-start,%di mov $0xa000,%bx mov %bx,%es mov $(80*2),%cx cmp $0x08,%al je putc.bs cmp $0x0d,%al je putc.cr cmp $0x0a,%al je putc.lf cmp $0x5c,%al /* \ */ jne 1f mov $0xfc,%al 1: movb $0xe1,%es:0x2000(%di) stosw jmp putc.scr putc.bs: test %di,%di jz putc.move dec %di dec %di movb $0xe1,%es:0x2000(%di) movw $0x20,%es:(%di) jmp putc.move putc.cr: mov %di,%ax div %cx sub %dx,%di jmp putc.move putc.lf: add %cx,%di putc.scr: cmp $(80*2*25),%di /* Scroll screen */ jb putc.move push %ds mov %bx,%ds mov $(80*2),%si xor %di,%di mov $(80*24/2),%cx rep movsl xor %ax,%ax mov $0x20,%al mov $80,%cl rep stosw pop %ds mov $(80*24*2),%di putc.move: mov %di,MEM_REL+cursor-start /* Move cursor */ mov $0x13,%ah mov %di,%dx int $0x18 popa lret cursor: .word 0 #ifdef SET_MACHINE_TYPE /* * Set machine type to PC98_SYSTEM_PARAMETER. */ set_machine_type: xor %edx,%edx mov %dx,%ds // mov $MEM_SYS,%ax // mov %ax,%es /* Wait V-SYNC */ vsync.1: inb $0x60,%al test $0x20,%al jnz vsync.1 vsync.2: inb $0x60,%al test $0x20,%al jz vsync.2 /* ANK 'A' font */ xor %al,%al outb %al,$0xa1 mov $0x41,%al outb %al,$0xa3 /* Get 'A' font from CG window */ push %ds mov $0xa400,%ax mov %ax,%ds xor %eax,%eax xor %bx,%bx mov $4,%cx font.1: add (%bx),%eax add $4,%bx loop font.1 pop %ds cmp $0x6efc58fc,%eax jnz m_epson m_pc98: or $M_NEC_PC98,%edx mov $0x0458,%bx mov (%bx),%al test $0x80,%al jz m_not_h98 or $M_H98,%edx jmp 1f m_epson: or $M_EPSON_PC98,%edx m_not_h98: or $M_NOT_H98,%edx 1: inb $0x42,%al test $0x20,%al jz 1f or $M_8M,%edx 1: mov $0x0400,%bx mov (%bx),%al test $0x80,%al jz 1f or $M_NOTE,%edx 1: mov $PC98_MACHINE_TYPE,%bx mov %edx,%es:(%bx) ret #endif /* Messages */ msg_eread: .asciz "Error\r\n" .org PRT_OFF,0x90 /* Partition table */ .fill 0x30,0x1,0x0 .byte 0x80, 0x00, 0x01, 0x00 .byte 0xa5, 0xff, 0xff, 0xff .byte 0x00, 0x00, 0x00, 0x00 .byte 0x50, 0xc3, 0x00, 0x00 .word 0xaa55 # Magic number