「手探りでCUI OS作成に挑む」連載
この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は「手探りでCUI OS作成に挑む」連載目次を御覧下さい。
目的
将来BIOSを作るに当たり、標準BIOSの割り込みは使えなくなるので、先ずはVRAMへ直接書き込み文字を出力する部分の処理を自分で書きました。
文字は緑にしてみました。
出力する文字のASCIIコードをALレジスタへ格納し、以下のように呼び出すと画面上に緑でが表示されます。
mov al, 'H'
int 0x2F
検証コード
org 0x7C00
bits 16
start:
; IVTの0x2F番地にハンドラを登録
mov ax, cs ; 現在のコードセグメントを取得
mov ds, ax ; DSをコードセグメントに設定
mov si, 0x2F * 4 ; IVTの0x2F番地に移動
; IVT[0x2F] にハンドラのアドレスを設定
lea dx, int10_handler ; ハンドラのアドレスを取得
mov word [si], dx ; オフセットを設定(低位)
mov word [si + 2], cs ; セグメントを設定(高位)
; VRAMを黒背景で初期化
mov ax, 0xB800
mov es, ax
xor di, di
mov cx, 2000 ; 80x25x2 = 4000バイト
mov ax, 0x0720 ; 空白 + 黒背景/灰色文字
rep stosw ; 一気にVRAMを埋める
; 自作した呼びだしでHを出力する
mov al, 'H'
int 0x2F
; カーソル位置を左上(0,0)に移動
mov dx, 0x3D4 ; VGAコントローラ
mov al, 0x0F ; 低位バイト
out dx, al
inc dx
mov al, 0x00
out dx, al
dec dx
mov al, 0x0E ; 高位バイト
out dx, al
inc dx
mov al, 0x00
out dx, al
cli
loop:
hlt
jmp loop
; int 0x2F ハンドラ(空いている番号に追加)
int10_handler:
push ax
; セグメントレジスタを設定(VRAMへのアクセス用)
mov ax, 0xB800
mov es, ax ; ES = 0xB800(VRAMセグメント)
pop ax
; 画面左上(1行目1列目)に 'H' を緑色で表示
mov byte [es:0], al ; 文字
mov byte [es:1], 0x02 ; 属性(緑色)
.iret:
iret ; 中断処理を終了
times 510-($-$$) db 0
dw 0xAA55
動作確認
nasm -f bin boot.asm -o boot.bin
qemu-system-i386 -fda boot.bin
8086実機での動作
コンパクトフラッシュへ書き込む命令
sudo dd if=boot.bin of=/dev/sdc bs=512 count=1 conv=notrunc