; haribote-ipl_ ; TAB=4 CYLS EQU 10 ;; 読み込むシリンダ数の設定 ORG 0x7c00 ;; このプログラムの読み込み位置 JMP entry ;; 本体コードへジャンプ ;; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述 DB 0x90 ; NULL DB "HARIBOOT" ; ブートセクタの名前を自由に書いてよい(8バイト) DW 512 ; 1セクタの大きさ(512にしなければいけない) DB 1 ; クラスタの大きさ(1セクタにしなければいけない) DW 1 ; FATがどこから始まるか(普通は1セクタ目からにする) DB 2 ; FATの個数(2にしなければいけない) DW 224 ; ルートディレクトリ領域の大きさ(普通は224エントリにする) DW 2880 ; このドライブの大きさ(2880セクタにしなければいけない) DB 0xf0 ; メディアのタイプ(0xf0にしなければいけない) DW 9 ; FAT領域の長さ(9セクタにしなければいけない) DW 18 ; 1トラックにいくつのセクタがあるか(18にしなければいけない) DW 2 ; ヘッドの数(2にしなければいけない) DD 0 ; パーティションを使ってないのでここは必ず0 DD 2880 ; このドライブ大きさをもう一度書く DB 0,0,0x29 ; よくわからないけどこの値にしておくといいらしい DD 0xffffffff ; たぶんボリュームシリアル番号 DB "HARIBOTEOS "; ディスクの名前(11バイト) DB "FAT12 " ; フォーマットの名前(8バイト) RESB 18 ; とりあえず18バイトあけておく ;; -- START --------------------------------------------------------- ;; ------------------------------------------------------------------ entry: XOR AX,AX ;; セグメントの初期化 MOV SS,AX ;; SS = 0x00 MOV SP,0x7c00 ;; SP = 0x7c00 MOV DS,AX ;; DS = 0x00 MOV AX,0x0820 ;; ディスク読み込みの設定 MOV ES,AX ;; ES = 0x0820 XOR CH,CH ;; シリンダ XOR DH,DH ;; ヘッド MOV CL,2 ;; セクタ MOV AX, msg_start ;; ipl10.nasの開始 CALL print ;; デバッグ情報の出力 ;; ------------------------------------ ;; ディスクから読み込み ;; ------------------------------------ MOV AX, msg_read ;; 読み込み開始 CALL print ;; デバッグ情報の出力 readloop: XOR SI,SI ;; 読み込み失敗回数を数えるレジスタ retry: MOV AH,0x02 ;; ディスク読み込み(BIOS) MOV AL,1 ;; 1セクタ XOR BX,BX ;; バッファ(ES:BX) XOR DL,DL ;; Aドライブ INT 0x13 ;; BIOS CALL JNC next ;; 成功ならnextへ進む INC SI ;; 読み込み失敗回数をインクリメント CMP SI,5 ;; SIと5を比較 JAE error ;; 読み込み失敗回数が5以上ならerrorへ進む XOR AH,AH ;; ドライブのリセット(BIOS) XOR DL,DL ;; Aドライブ INT 0x13 ;; BIOS CALL JMP retry ;; 再チャレンジだ、このやろ〜 next: MOV AX,ES ;; ES:BXを次のセクタを読み込むためのメモリアドレスにするため ADD AX,0x0020 ;; ESに512(0x200)を加算するのだが、セグメントに MOV ES,AX ;; 定数を渡す命令は無いので、3つの命令で実現している INC CL ;; セクタをインクリメント CMP CL,18 ;; CLと18を比較 JBE readloop ;; 読み込みセクタ数が18以下ならreadloopへ進む MOV CL,1 ;; 18セクタ読み終えたので再び1に戻す ADD DH,1 ;; ヘッダをインクリメント(次は裏側から読む) CMP DH,2 ;; DHと2を比較 JB readloop ;; まだ両面読み終わってないならreadloopへ進む XOR DH,DH ;; 両面読み終えたので再びヘッダを0に戻す ADD CH,1 ;; シリンダをインクリメント CMP CH,CYLS ;; CHとCYLSを比較 JB readloop ;; 読み込んだシリンダ数が ;; 読み込み予定のシリンダ数より小さいならreadloopへ進む MOV AX, msg_ok ;; 読み込み完了 CALL print ;; デバッグ情報の出力 ;; ------------------------------------ ;; 読み込みデータの実行(haribote.sys) ;; ------------------------------------ MOV AX, msg_exec ;; 読み込みデータの実行 CALL print ;; デバッグ情報の出力 MOV [0x0ff0],CH ;; IPLがどこまで読んだのかをメモ JMP 0xc200 ;; ------------------------------------ ;; 文字列の出力 ;; ------------------------------------ print: PUSHA MOV SI,AX ;; SIへ出力する文字列アドレスを入れる putloop: MOV AL,[SI] ;; 1文字読み込む CMP AL,0 ;; 読み込んだ文字が0x00なら JE putfin ;; 文字の終端と判断してputfinへ進む MOV AH,0x0e ;; 一文字表示ファンクション MOV BX,15 ;; カラーコード INT 0x10 ;; BIOS CALL INC SI ;; SIを次の文字のアドレスにする JMP putloop putfin: POPA ret msg_start: DB 0x0a, "ipl10.nas", 0x0a, 0 msg_read: DB " reading disk to memory ... ", 0 msg_exec: DB " jump to reading data", 0 msg_ok: DB "ok!", 0x0a, 0 msg_error: DB "error!", 0x0a, 0 ;; ------------------------------------ ;; エラー時の処理 ;; ------------------------------------ error: MOV AX, msg_error ;; 読み込みデータの実行 CALL print ;; デバッグ情報の出力 XOR AX,AX MOV ES,AX ;; ES = 0x00 fin: HLT ;; 何かあるまでCPUを停止させる JMP fin ;; 無限ループ ;; どこまでも続くループ、終わらない素敵なループ(電気グループ) ;; ------------------------------------------------------------------ ;; ----------------------------------------------------------- EOF -- RESB 0x7dfe-$ ;; 0x7dfeまでを0x00で埋める命令 DB 0x55, 0xaa ;; 最後の2バイトは固定値