「手探りでCUI OS作成に挑む」連載
この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は「手探りでCUI OS作成に挑む」連載目次を御覧下さい。
目的
BIOSを開発する前準備として割り込みの処理を少しずつ実装しています。
今日は文字入力を実装しました。
実装コード
org 0x7C00
bits 16
jmp start
; データ定義
msg_prompt db "Press a-j: ", 0
msg_newline db 13, 10, 0 ; エンターで改行 0x0D,0x0A,0に等しい
start:
; 设置栈
mov ax, 0x9000
mov ss, ax
mov sp, 0xFFFE
mov ax, cs
mov ds, ax
mov es, ax
mov si, 0x2F * 4 ; IVTの0x2F番地に登録する
; IVT[0x2F] にキーボード処理のアドレスを設定
lea dx, get_key ; DXへアドレスを格納
mov word [si], dx ; オフセットを設定(低位)
mov word [si + 2], cs ; セグメントを設定(高位)
; Press a-jと画面表示
mov si, msg_prompt
call print_string
main_loop:
; 自分で定義した文字入力の処理を呼び出す
int 0x2F
cmp al, 0 ; a-j以外は
je main_loop ; 表示しない
; 入力された文字を画面表示
call print_char
; 改行
mov si, msg_newline
call print_string
jmp main_loop ; 次の文字の入力へ
; 文字表示
print_char:
pusha
mov ah, 0x0E
int 0x10
popa
ret
; 文字列表示
print_string:
pusha
mov ah, 0x0E
.print_loop:
lodsb
or al, al
jz .done
int 0x10
jmp .print_loop
.done:
popa
ret
; キーボードからの入力を受け取り対応するASCIIコードをAL経由で返す
get_key:
in al, 0x64 ; 0x64ポート経由で入力されているかを確認
test al, 1 ; 0ビット目 1:有り 0:無し
jz get_key ; 押されていなければget_keyへ戻って初めから
in al, 0x60 ; 押されたキーの番号を取得
; キーの番号最高位が 0:押された 1:離された
test al, 0x80
jnz get_key ; 離された場合は入力と見做さない
; キーの番号からASCIIコードへ変換していく(今回は検証が目的な為、少数の実装に留める)
cmp al, 0x1E ; 'a'
je .a
cmp al, 0x30 ; 'b'
je .b
cmp al, 0x2E ; 'c'
je .c
cmp al, 0x20 ; 'd'
je .d
cmp al, 0x12 ; 'e'
je .e
cmp al, 0x21 ; 'f'
je .f
cmp al, 0x22 ; 'g'
je .g
cmp al, 0x23 ; 'h'
je .h
cmp al, 0x17 ; 'i'
je .i
cmp al, 0x24 ; 'j'
je .j
xor al, al ; a-j以外は0を返す
ret
.a:
mov al, 'a'
ret
.b:
mov al, 'b'
ret
.c:
mov al, 'c'
ret
.d:
mov al, 'd'
ret
.e:
mov al, 'e'
ret
.f:
mov al, 'f'
ret
.g:
mov al, 'g'
ret
.h:
mov al, 'h'
ret
.i:
mov al, 'i'
ret
.j:
mov al, 'j'
ret
times 510-($-$$) db 0
dw 0xAA55
動作確認
QEMU
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
起動はしたのですが、何を押しても反応がなく、適当なキーを何回か押していると、いきなり最後に押したキーが大量に表示されてしまいました。
QEMU上ではうまく動作しましたが、実機では意図通りに動かすにはもう少し研究が必要なようです。
実機のBIOSは変更できないため、これから作ろうとしているBIOSコードはQEMUのようなエミュレータ上で動作させることしかできません。
そういう意味では、実機で動かす意味は本質的には無いのですが、「なぜ動かないのか」には非常に興味があるため、今後の課題とします。