自作OSに挑戦する日記 14日目
「30日でできる!OS自作入門」を読んで分かったことや、とりあえず書いておきたいことなどを書いていきます。
この本はChapterが1から30まであるので、各チャプター毎に1記事書いていきます。
Chapter 14 「高解像度・キー入力」
今回やった内容
- 高解像度化
- キー入力を画面に反映する
環境
- メインPC
- MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)
- macOS Mojave 10.14
- 自作OSを動作させる環境
作業記録
今まで320 x 200の画面で開発をしていたのですが、もっと高解像度にします!
解像度変更は起動時に行い、アセンブリで書きます(久々のアセンブリだ…)。
; VBE存在確認 MOV AX, 0x9000 MOV ES, AX MOV DI, 0 MOV AX, 0x4f00 INT 0x10 CMP AX, 0x004f JNE scrn320 ; VBEバージョン確認 MOV AX, [ES:DI + 4] CMP AX, 0x0200 JB scrn320 ; 画面モード情報を取得する (指定した画面モードが使えない場合はjmp) MOV CX, VBEMODE MOV AX, 0x4f01 INT 0x10 CMP AX, 0x004f JNE scrn320 ; 画面モード情報を確認する (色数=8? パレットモード使える? 画面モードに0x4000足しても大丈夫?) CMP BYTE [ES:DI + 0x19], 8 JNE scrn320 CMP BYTE [ES:DI + 0x1b], 4 JNE scrn320 MOV AX, [ES:DI + 0x00] AND AX, 0x0080 ; bit7にフラグが立っているかどうか JZ scrn320 ; 画面モード切り替え! newwindowmode: ORG 0xc200 MOV BX, VBEMODE + 0x4000 ; VBEの1024x768x8bitカラー MOV AX, 0x4f02 INT 0x10 MOV BYTE[VMODE], 8 ; 画面の設定をメモする MOV AX, [ES:DI + 0x12] MOV WORD[SCRNX], AX MOV AX, [ES:DI + 0x14] MOV WORD[SCRNY], AX MOV EAX, [ES:DI + 0x28] MOV DWORD[VRAM], EAX JMP keystatus ; 解像度を320x200にする scrn320: ORG 0xc200 MOV AL, 0x13 ; 320x200x8bitカラー MOV AH, 0x00 INT 0x10 MOV BYTE[VMODE], 8 ; 画面の設定をメモする MOV WORD[SCRNX], 320 MOV WORD[SCRNY], 200 MOV DWORD[VRAM], 0x000a0000 keystatus: MOV AH, 0x02 ; キーボードの設定をBIOSから教えてもらう INT 0x16 MOV [LEDS], AL
高解像にするためにはVBE「VESA BIOS extention (VESA BIOS拡張 : VBE) 」を使う必要があるのですが、もしVBEが使えなかった場合も考えて処理を書いています。
VBEが使えるかは「存在確認」「バージョン確認」「画面モード情報確認」の3ステップによって確認しています。もしどれか1つでも引っかかった場合には今までのように320 x 200の解像度で起動するようにし、全ての確認をパスした場合にはVBEを使って高解像度に設定するようにしています。
…ということで高解像度になったHariboteOSくんがこちらです。
ひゃーーーーーー pic.twitter.com/MfKp6UAmdp
— ゆん (@yn0014) March 8, 2019
画面が広すぎる…!解像度がか変わっただけですが、これだけでかなり進化したような感じがします。
高解像度化の次はキー入力です。今まではキー入力を割り込みデータそのままで画面に表示していたのですが、これからは対応表に基づいて表示するようにします。対応表中の「0」は定義されていないキーです。
// 飛んできたデータとキー文字の対応表 char keytable[0x54] = { 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0, 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '0' };
キー文字がちゃんと表示できるようになったので、ウィンドウ内に入力された文字を16文字まで表示できるようなフォームを作成してみます。入力されるたびに cursor_x という変数を変化させることでフォームみたいな動きを再現しています。
while(1){ io_cli(); if(fifo32_status(&osfifo) == 0){ io_stihlt(); } else{ int data = fifo32_get(&osfifo); io_sti(); if(256 <= data && data <= 511){ // キーボード msprintf(s, "%x", data - 256); putstr8_ref(sheet_back, 0, 20, COL8_FFFFFF, COL8_008484, s, 2); // ウィンドウへの入力 extern char keytable[0x54]; if(data < 256 + 0x54 && keytable[data - 256] != 0 && cursor_x < 144){ // 通常文字 s[0] = keytable[data - 256]; s[1] = 0; putstr8_ref(sheet_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, s, 1); cursor_x += 8; } if(data == 256 + 0x0e && cursor_x > 8){ // BackSpace putstr8_ref(sheet_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1); cursor_x -= 8; } // カーソル位置更新して再描画 boxfill8(sheet_window->buf, sheet_window->buf_width, cursor_color, cursor_x, 28, cursor_x + 7, 43); sheet_refresh(sheet_window, cursor_x, 28, cursor_x + 8, 44); } } }
これを実行してみると…
14日目完成!
— ゆん (@yn0014) March 8, 2019
かなり進化した… pic.twitter.com/numreYC2jx
ちゃんとキー入力が正しく画面に表示され、しかも文字列の入力が可能になっています…!OS感がかなり増しました…
まとめ
高解像度化とキー入力の実装をしました。13日目から14日目にかけての進化具合が圧倒的すぎる…。