ウォンツテック

そでやまのーと

bootacient.SのFDからの読み込み部分を先に書いた。
bootacient.S, bootmiddle.Sはそれぞれfirstboot, secondbootの役割でこれらは0x90000, 0x90200に置きkernelは0x1000に置く。
また、kernelのstack領域はとりあえず0x9f000としておいた。

/*
 *  @File        bootacient.S
 *  @Brief       The initial boot section of Sodex
 *
 *  @Author      Sodex
 *  @Revision    0.1
 *  @License     suspension
 *  @Date        create: 2007/04/05  update: 2007/04/05
 *
 *  Copyright (C) 2007 Sodex
 */

BOOTSEG         = 0x07C0
INITSEG         = 0x9000
KERNEL_SEG       = 0x0100
KERNEL_STACK_SEG = 0x9000
KERNEL_STACK_OFFSET = 0xf000

# We won't have to increase the BOOT_SECTS to more 18
ACIENT_SECTS    = 1
MIDDLE_SECTS    = 1
KERNEL_SECTS    = 46
BOOT_SECTS      = ACIENT_SECTS + MIDDLE_SECTS
KERNEL_FIRST    = KERNEL_SECTS - BOOT_SECTS

# This is the default size of general FD formatted at 1.44MB.
SECTORS         = 18

.code16
.text

.global _start, printstr
_start:

        jmpl    $BOOTSEG, $start2

start2:
        xorw    %si, %si
        xorw    %di, %di
        movw    $BOOTSEG, %ax
        movw    %ax, %ds
        movw    $INITSEG, %ax
        movw    %ax, %es
        movw    $0x100, %cx
        cld
        rep     movsw
        jmpl    $INITSEG, $next

next:
        movw    %ax, %ds
        movw    $KERNEL_STACK_SEG, %ax
        movw    %ax, %ss
        movw    $KERNEL_STACK_OFFSET, %sp


# Clear the display and the message is printed
# before we load the boot_middle and kernel

        movb    $0x3, %al       # Clear the display
        movb    $0, %ah
        int     $0x10
        movw    $loader_mes, %si
        call    printstr

# Reset FD
        call    reset_fd
        jmp     read_middleboot

/* Read next boot section from floppy drive.
 * The data is read from fd and It is set at ES:BX of the memory point.
 * The reserved memory at first is the parameter of FD.
 *  "secotr:" is sectors of current track ( 1 <= sector <= 18 )
 *  "head:" is current head ( 0 <= head <= 1 )
 *  "track:" is current track ( 0 <= track <= 79 )
 */
        sector: .byte 1
        track:  .byte 0
        head:   .byte 0
        dummy:  .byte 0

read_middleboot:
        movw    $0x200, %bx     # "es" is already set at 0x9000
        movb    $0x2, %al       # boot acient code spend a sect
        movw    $sector, %si
        movb    %al, (%si)

        movb    $0x2, %ah           # AH is BIOS COMMAND, The no.2 indicates
                                    # reading disk sectors
        movb    $MIDDLE_SECTS, %al  # AL is Num of sectors to read
        movb    (%si), %cl          # CL is the sector
        movb    1(%si), %ch         # CH is the track
        movb    2(%si), %dh         # DH is the head
        movb    $0, %dl             # DL is the drive(always 0)
        int     $0x13
        jc      read_error

        incb    (%si)
        call    reset_fd

/* Read the kernel section from FD.
 * The data is read from fd and It is set at ES:BX.
 */
        xorw    %bx, %bx
        movw    $KERNEL_SEG, %ax
        movw    %ax, %es            # ES:BX = 0x0100:0x0000(0x1000)

        movw    $KERNEL_SECTS, %di  # set the num of kernel sects to di
        movb    $0x2, %ah           # AH is BIOS COMMAND, The no.2 indicates
                                    # reading disk sectors
        movb    $KERNEL_FIRST, %al
                                    # The num sector must be between 1 and 18.
        movb    (%si), %cl          # CL is the sector
        movb    1(%si), %ch         # CH is the track
        movb    2(%si), %dh         # DH is the head
        movb    $0, %dl             # DL is the drive(always 0)
        int     $0x13
        jc      read_error

        addb    %al, %bh
        addb    %al, %bh            # bx += 2*al*256 (add reading bytes)

        movb    %ah, %ah            # al is no. of read sectors
        subw    %ax, %di

        movb    $0x0, (%si)         # sector is 0
        movb    $0x1, 2(%si)        # head is 1

read1:
        cmpw    $SECTORS, %di
        ja      left_sects_over18
        movw    %di, %ax
        xorb    %ah, %ah
        call    read_it
        jmp     read_end

left_sects_over18:
        movb    $SECTORS, %al
        call    read_it
        jmp     read1

read_end:
        call    reset_fd
        jmp     middle_start

/* Read FD's data
 * Before using this function, we must set the following parameter
 *  ES:BX  -  sent address
 *  AL     -  Num of read sectors
 *  sector, track, head  -  FD parameter
 */
read_it:
        movb    $0x2, %ah           # AH is BIOS COMMAND, The no.2 indicates
                                    # reading disk sectors

        movb    (%si), %cl          # CL is the sector
        movb    1(%si), %ch         # CH is the track
        movb    2(%si), %dh         # DH is the head
        movb    $0, %dl             # DL is the drive(always 0)
        int     $0x13
        jc      read_error

        addb    %al, %bh
        addb    %al, %bh            # bx += 2*al*256 (add reading bytes)

        movb    %ah, %ah            # al is no. of read sectors
        subw    %ax, %di

        # if head is 0, then we set head to 1
        # else if head is 1, then we increment track and set head to 0
        cmpb    $0x0, 2(%si)
        jnz     read_it_next
        movb    $0x1, 2(%si)
        jmp     read_it_end

read_it_next:
        movb    $0x0, 2(%si)
        incb    1(%si)

read_it_end:
        ret

/* Reset floppy drive
 * Set AH = 0, which indicate to reset drive
 * Set AL = 0, which indicate first floppy drive.
 * INT 0x13: BIOS Disk services
 */
reset_fd:
        xorw    %ax, %ax
        xorb    %dl, %dl        # dl is num of drive
        int     $0x13
        jnc     fd_reset_ok
        movw    $fd_reset_error_mes, %si
        call    printstr
        jmp     halt
fd_reset_ok:
        ret

read_error:
        movw    $fd_read_error_mes, %si
        call    printstr
        jmp     halt

printstr:
        pushw   %ax
printstr_start:
        lodsb
        cmpb    $0, %al
        jz      printstr_end
        movb    $0x0e, %ah
        movb    $0, %bh
        int     $0x10
        jmp     printstr_start
printstr_end:
        popw    %ax
        ret

halt:
#       hlt
        jmp     halt

loader_mes:
        .ascii  "Loading...\r\n"
        .byte   0
fd_reset_error_mes:
        .ascii  "The floppy drive failed reset..\r\n"
        .byte   0
fd_read_error_mes:
        .ascii  "read error at the floppy drive..\r\n"
        .byte   0

        .org 510
        .word 0xAA55