自作OSに挑戦する日記 30日目 & 31日目

 「30日でできる!OS自作入門」を読んで分かったことや、とりあえず書いておきたいことなどを書いていきます。
 この本はChapterが1から30まであるので、各チャプター毎に1記事書いていきます。

Chapter 30「高度なアプリケーション」

今回やった内容

  • 計算機
  • テキストビューア
  • 音楽プレイヤー
  • 画像ビューア
  • IPL改良

環境

作業記録

 前回まででOSが完成したので、最終日はアプリケーションを作っていきます。

計算機

 入力した計算式の結果を出力するアプリです。

f:id:guguru0014:20190526142855p:plain

テキストビューア

 テキストファイルの閲覧が出来るアプリです。h, j, k ,l キーで操作することができます。

f:id:guguru0014:20190526143426p:plain

音楽プレイヤ

 BEEP音で音楽を再生するアプリです。QEMUではBEEP音のエミュレートができないため、実際に音楽を聴くことは出来ませんでした…。

f:id:guguru0014:20190526143748p:plain

画像ビューア

 JPEG or BMP形式の画像ファイルを閲覧できるアプリです。

f:id:guguru0014:20190526143844p:plain
👍

IPL改良

 HariboteOS起動の高速化をします。ディスク読み込みを1セクタずつ行うのではなく、複数のセクタをまとめて読み込むようにします。  ALレジスタに読み込むセクタ数を指定した後、BIOSの0x13番を呼ぶことで複数セクタをまとめて読み込むことができます。

; ディスク読み込み(高速版), 複数セクタを同時に読み込む
; ES : 読み込み番地, CH : シリンダ, DH : ヘッダ, CL : セクタ, RX : 読み込みセクタ数
readfast:
        MOV      AX, ES            ; <ESからセクタ数(AL)を計算>
        SHL      AX, 3           ; AXを32で割ってAHに結果を代入したのと同じ動きをする AX -> AH | AL
        AND      AH, 0x7f        ; 128で割った余りを求める
        MOV      AL, 128         ; AL = 128 - AH => 一番近い64KBの境界まで何セクタあるか
        SUB      AL, AH            ; 1セクタ(512KB) * 128 - 1セクタ(512KB) - AH(端数)

        MOV      AH, BL            ; ALの値を調節する
        CMP  BH, 0           ; if(BH != 0){ AH = 18; }
        JE       .skip1
        MOV      AH, 18
.skip1:
        CMP      AL, AH            ; if(AL > AH){ AL = AH; }
        JBE      .skip2
        MOV      AL, AH
.skip2:
        MOV      AH, 19
        SUB      AH, CL
        CMP  AL, AH            ; if(AL > AH) { AL = AH; }
        JBE  .skip3
        MOV      AL, AH
.skip3:
        PUSH BX               ; 失敗回数を数えるレジスタ
        MOV  SI, 0

retry:
        MOV      AH, 0x02        ; ディスク読み込み命令のために設定
        MOV      BX, 0
        MOV      DL, 0x00
        PUSH ES
        PUSH DX
        PUSH CX
        PUSH     AX
        INT  0x13           ; ディスク読み出し(ALに設定したセクタ分読む)
        JNC      next         ; エラーが起きなければnextへ
        ADD      SI, 1
        CMP      SI, 5           ; 5回連続で読み込みに失敗したら
        JAE      error
        MOV      AH, 0x00
        MOV      DL, 0x00
        INT      0x13           ; ドライブリセット
        POP  AX
        POP  CX
        POP  DX
        POP  ES
        JMP  retry
next:
        POP  AX
        POP  CX
        POP  DX
        POP  BX
        SHR      BX, 5           ; BXを512バイト単位にする(5ビット右シフト)
        MOV      AH, 0
        ADD      BX, AX
        SHL      BX, 5           ; BXを512バイト単位から32バイト単位へ(5ビット右シフト)
        MOV      ES, BX            ; ES += AL * 0x20
        POP  BX
        SUB  BX, AX
        JZ       .ret
        ADD      CL, AL
        CMP  CL, 18          ; if(CL <= 18){ goto readfast; }
        JBE      readfast
        MOV      CL, 1
        ADD  DH, 1
        CMP  DH, 2           ; if(DH < 2){ goto readfast; }
        JB       readfast
        MOV  DH, 0
        ADD  CH, 1
        JMP  readfast
.ret:
        RET

 AXレジスタの値を32で割ってその値をAHレジスタから取り出すという操作を、左シフト操作で行なっています。

f:id:guguru0014:20190526145527j:plain
AXレジスタの上位8ビットがAH、下位8ビットがAL


 これで30日本全ての内容が終わりました!!

(全体の)まとめ

 自作OS本終わりです!!完成までの期間は4ヶ月でした〜!ブログ完走も出来たので良かったです。

 30日という短い期間でOSが完成するのかと不思議でしたが、キーボード操作やマウス操作、例外などの割り込み処理や、メモリ管理、マルチタスクシステム、ウィンドウシステムなど…OSの基本的な機能は全て実装することができました。 途中、筆者の方のオリジナルプログラムを使う場面で苦戦しましたが、その分得られるものが大きかったです。

 これからは低い方に潜っていきたいと思います。4月にHelloWorld本を手に入れたのでそれを読みつつ、OS再自作のための計画を建てていきます。

 最後に…自作OS本オススメなのでぜひ読んでみてください!