備忘録やめた

備忘録として使用していたけどやめた.このブログに載せてあるコードのライセンスは別途記載がない限りWTFPL OR NYSLです.

VBE設定コードを分離する

要約

tokuchan3515.hatenablog.com 以前,はりぼてOSの解像度と色深度を上げる方法を紹介しましたが,ここで書いたコードが長いので,別のファイルにコードを移し,元のファイルに%includeでインクルードすることでコードを分割します.asmファイルとMakefileの場所が異なる場合,nasmのオプションに-iを追加することで,nasmがasmファイルがあるディレクトリも検索するようにします.

はじめに

以前の記事で,はりぼてOSの解像度と色深度を上げる方法を紹介しましたが,その結果,コードが長くなり,スクロールを何度もしないといけなくなるなど,コード編集に影響を及ぼすようになりました.コードを分割することで,編集を容易に行なうことが出来,能率が上がります.今回は,nasmの%includeを使用し,別のファイルに移したコードをインクルードすることでコードを分割します.

やり方

新しくasmファイルを作成し,コードを移す

ここではvbe.asmとします.以下のコードが書かれています.このコードは前回紹介したコードを編集したものです*1

    VBE           EQU     0x9000
    BPP           EQU     0x0ff2          ; 色数に関する情報。何ビットカラーか?
    SCRNX         EQU     0x0ff4          ; 解像度のX
    SCRNY         EQU     0x0ff6          ; 解像度のY
    VRAM          EQU     0x0ff8          ; グラフィックバッファの開始番地
    VBEMODE       EQU     0x0ffc          ; VBE mode number. word size
    VBE_INFO_SIZE EQU 0x0200

    ; Get VBE Info
    MOV           AX,VBE
    MOV           ES,AX
    MOV           DI,0
    MOV           AX,0x4f00
    INT           0x10

    ; Loop initialization
    MOV           BYTE[BPP],8
    MOV           WORD[SCRNX],320
    MOV           WORD[SCRNY],200
    MOV           DI,VBE_INFO_SIZE

select_mode:
    VMODE_PTR     EQU 14
    ; Get VESA mode number
    MOV           SI,WORD[ES:VMODE_PTR]
    MOV           FS,WORD[ES:VMODE_PTR+2]
    MOV           CX,WORD[FS:SI]

    CMP           CX,0xffff
    JE            set_vbe

    ; Get VESA mode information.
    MOV           AX,0x4f01

    INT           0x10

    CMP           AX,0x004f
    JNE           next_mode

    ; Check if this graphics mode supports linear frame buffer support.
    MOV           AX,WORD[ES:DI]
    AND           AX,0x80
    CMP           AX,0x80
    JNE           next_mode

    ; Check if this is a packed pixel
    MOV           AX,WORD[ES:DI+27]
    CMP           AX,4
    JE            valid_mode

    ; Check if this is a direct color mode
    CMP           AX,6
    JE            valid_mode

    JMP           next_mode

valid_mode:
    ; Compare dimensions
    MOV           AX,WORD[ES:DI+18]
    CMP           AX,WORD[SCRNX]
    JB            next_mode

    MOV           AX,WORD[ES:DI+20]
    CMP           AX,WORD[SCRNY]
    JB            next_mode

    ; If bpp is not 24 bit or 32 bit, don't use this.
    CMP           BYTE[ES:DI+25],24
    JB            next_mode

    ; Set dimension and bits number
    MOV           AX,WORD[ES:DI+18]
    MOV           WORD[SCRNX],AX

    MOV           AX,WORD[ES:DI+20]
    MOV           WORD[SCRNY],AX

    MOV           AL,BYTE[ES:DI+25]
    MOV           BYTE[BPP],AL

    MOV           AX,WORD[ES:DI+40]
    MOV           WORD[VRAM],AX
    MOV           AX,WORD[ES:DI+40+2]
    MOV           WORD[VRAM+2],AX

    MOV           WORD[VBEMODE],CX

next_mode:
    MOV           AX,WORD[ES:VMODE_PTR]
    ADD           AX,2
    MOV           WORD[ES:VMODE_PTR],AX

    JMP           select_mode

set_vbe:
    MOV           AX,0x4f02
    MOV           BX,WORD[VBEMODE]
    OR            BX,0x4000
    INT           0x10

定数定義は元のファイルに残しておくことも可能です.例えばコードの先頭にあるVBE EQU 0x9000などを移さずに元のファイルに置くことが出来ます.しかしながら,linterが警告を発するはずです.その定数が元のファイル内の他の場所で使用されていないならば,定数定義を移すことをおすすめします.

また,C言語のヘッダファイルのように,インクルードガードを使用することも可能です.今回はインクルードされる場所が1箇所しかないため,インクルードガードを使用しません.インクルードガードを使用する場合,以下のように書いてください.これは,NASM - The Netwide Assemblerの4.6.1からの引用です.

%ifndef MACROS_MAC 
    %define MACROS_MAC 
    ; now define some macros 
%endif

;now define some macrosの所にコードを書いてください.

元のファイルに%include文を書く

%include "vbe.asm"

を元のファイルに書きます.これは移したコードがあった場所に記述してください.タブルクオーテーションマークも含めてください.この場所にvbe.asmの内容がインクルードされます.

Makefile内のnasmのオプションに-iを追加

NASM - The Netwide Assemblerの4.6.1からの引用です.

Include files are searched for in the current directory (the directory you're in when you run NASM, as opposed to the location of the NASM executable or the location of the source file), plus any directories specified on the NASM command line using the -i option.

つまるところ,インクルードファイルの検索は,基本nasmの実行時のカレントディレクトリ内しか行われません.例えばasmディレクトリ内にvbe.asmが存在する場合,以下のように-iオプションを追加する必要があります.

nasm asm/head.asm -i asm/

ディレクトリ指定の際,最後のスラッシュが不要な環境もありますが,スラッシュなしだとディレクトリ指定されない環境も存在するようです*2.スラッシュを付けておくと確実です.

ところで,-I,すなわちiを大文字にしたオプションも-iオプションと同等です.NASM - The Netwide Assemblerの2.1.17からの引用です.

For Makefile compatibility with many C compilers, this option can also be specified as -I.

以上で準備完了です.makeを実行して動作確認してみてください.

*1:320x200への対応はYAGNIとして削除

*2:Travis CIの環境だとスラッシュ無しでエラーを吐く