3日目

今回のテーマは、IPLを作成しようということです。
IPLとは、初期プログラムローダのことです。

FDの内容をメモリに展開

FDの先頭512バイト(1セクタ)の次の512バイトをメモリ上に展開する方法について解説してあります。
ソースでは、下記の箇所が街頭箇所になります。

#ディスクを読み込む
     movw $0x0820, %ax
     movw %ax,     %es
     movb $0x00,   %ch  #シリンダ 0
     movb $0x00,   %dh  #ヘッド 0
     movb $0x02,   %cl  #セクタ 2

     movb $0x02,   %ah  #ディスク読み込み
     movb $0x01,   %al  #1セクタ
     movw $0x00,   %bx
     movb $0x00,   %dl  #Aドライブ
     int  $0x13         #ディスクBIOSコール
     jc error


メモリマップ、INT命令は、下記記事にあるリンクを参照して下さい。
2日目 - 未来設計図

10シリンダー分読むプログラム

.equ CYLS, 10

.text
.code16                                                                         
# 以下は標準的なFAT12フォーマットフロッピーディスクのための記述
    jmp entry
    .byte 0x90
    .ascii "HELLOIPL"         # ブートセクタの名前(8バイト)
    .word  512                # 1セクタの大きさ
    .byte  0x01               # クラスタの大きさ
    .word  1                  # FATの開始位置(普通は、1セクタ目から)
    .byte  0x02               # FATの個数
    .word  224                # ルートディレクトリ領域の大きさ(224エントリ)
    .word  2880               # このドライブの大きさ
    .byte  0xf0               # メディアのタイプ
    .word  9                  # FAT領域の長さ
    .word  18                 # 1トラックにあるセクタ数
    .word  2                  # ヘッドの数
    .int   0                  # パーティションの個数(未使用なので0)
    .int   2880               # このドライブの大きさをもう一度書く
    .byte  0x00, 0x00, 0x29   # ??
    .int   0xffffffff         # ボリュームシリアル番号
    .ascii "HELLO-OS   "      # ディスクの名前(11バイト)

readloop:
    movw $0x00,   %si  #失敗回数を数える
retry:
    movb $0x02,   %ah  #ディスク読み込み
    movb $0x01,   %al  #1セクタ
    movw $0x00,   %bx
    movb $0x00,   %dl  #Aドライブ
    int  $0x13         #ディスクBIOSコール
    jnc  next
    addw 1,       %si  #失敗回数をカウント
    cmp  $0x05,   %si  #5失敗したらエラー
    jae  error
    movb $0x00,   %ah
    movb $0x00,   %dl  #Aドライブ
    int  $0x12         #ドライブのリセット  
    jmp  retry

#----------------------------
#次のセクタを読み出すための処理
#----------------------------
next:
    movw %es,     %ax
    addw $0x0020, %ax  #0x0200(512バイト分)進める
    movw %ax,     %es
    addb $0x01,   %cl  #セクタ位置も更新
    cmpb $18,     %cl  #18セクタ分読み込んだ場合
    jbe  readloop      # cl <= 18だったら、readloopへ
    movb $1,      %cl
    addb $1,      %dh
    cmpb $2,      %dh  # dh < 2の場合は、readloopへ
    movb $0,      %dh
    add  $1,      %ch
    cmp  $CYLS,   %ch
    jb   readloop

#読み込み終わったけどとりあえずやることないので寝る
fin:
    hlt
    jmp fin

readloop:
    movw $0x00,   %si  #失敗回数を数える
retry:
    movb $0x02,   %ah  #ディスク読み込み
    movb $0x01,   %al  #1セクタ
    movw $0x00,   %bx
    movb $0x00,   %dl  #Aドライブ
    int  $0x13         #ディスクBIOSコール
    jnc  next
    addw 1,       %si  #失敗回数をカウント
    cmp  $0x05,   %si  #5失敗したらエラー
    jae  error
    movb $0x00,   %ah
    movb $0x00,   %dl  #Aドライブ
    int  $0x12         #ドライブのリセット  
    jmp  retry

#----------------------------
#次のセクタを読み出すための処理
#----------------------------
next:
    movw %es,     %ax
    addw $0x0020, %ax  #0x0200(512バイト分)進める
    movw %ax,     %es
    addb $0x01,   %cl  #セクタ位置も更新
    cmpb $18,     %cl  #18セクタ分読み込んだ場合
    jbe  readloop      # cl <= 18だったら、readloopへ
    movb $1,      %cl
    addb $1,      %dh
    cmpb $2,      %dh  # dh < 2の場合は、readloopへ
    movb $0,      %dh
    add  $1,      %ch
    cmp  $CYLS,   %ch
    jb   readloop

#読み込み終わったけどとりあえずやることないので寝る
fin:
    hlt
    jmp fin
error:
    movw $msg, %si

putloop:
    movb (%si), %al
    addw $1, %si
    cmpb $0, %al
    je fin
    movb $0x0e , %ah  #1文字表示
    movw $15, %bx     #カラーコード
    int $0x10         #ビデオBIOS呼び出し
    jmp putloop
    
#表示用データ
msg:
    .byte 0x0a, 0x0a
    .ascii "load error"                                                         
    .byte 0x0a
    .byte 0x00

    .org 0x1fe, 0x00
    .byte 0x55, 0xaa