自作OSに挑戦する日記 17日目

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

Chapter 17 「コンソール」

今回やった内容

  • 文字入力機能を強化する

環境

作業記録

 自作OS17日目、今回はコンソールの見た目を作っていくという感じでした。…いうことで完成したのがこちらです。

 コンソールウィンドウは今までと同じような感じで作りましたが、強化されたのが文字入力機能です。タスクごとに入力が分けれるようになったことや、記号や小文字の入力が可能になりました。

1. キー入力を受け取るタスクを変更できるようにする

 どのタスクが有効になっているかを保持するような変数を作ってあげます。そして、キー入力がされた時に変数の値を見てどのタスクに入力を渡すかを決めます。

 入力を受け取るタスクの切り替えはTabキーを押すことでできるようにします。また、make_window_title()という関数を作ることでタスク切り替え時にウィンドウタイトルの色が変えれるようになりました(なんとなくOSっぽい)。

// キーの状態
int key_to = 0;

// メインループ
while(1){
    /*  キーボードコントローラーへデータを送信する */
    if(fifo32_status(&keycmd_fifo) != 0 && keycmd_wait < 0){
        keycmd_wait = fifo32_get(&keycmd_fifo);
        wait_KBC_sendready();
        io_out8(PORT_KEYDAT, keycmd_wait);
    }

    io_cli();

    // FIFOバッファが空だった
    if(fifo32_status(&osfifo) == 0){
        task_sleep(task_main);
        io_sti();
        continue;
    }

    // FIFOバッファからデータを取得
    int data = fifo32_get(&osfifo);
    io_sti
    /*  キーボード  */
    if(256 <= data && data <= 511){
        ~略~
        // 入力タスク切り替え
        if(data == 0x0f + 256){
            make_window_title(buf_window, sheet_window->buf_width, "Window", key_to);
            make_window_title(buf_console, sheet_console->buf_width, "Console", 1 - key_to);
            sheet_refresh(sheet_window, 0, 0, sheet_window->buf_width, 21);
            sheet_refresh(sheet_console, 0, 0, sheet_console->buf_width, 21);
            key_to = 1 - key_to;
            continue;
        }

        // 必要があればコンソールタスクにキーデータを送る
        if(key_to == 1){
            if(keydata != 0){
                fifo32_put(&task_console->fifo, keydata + 256);
            }else if(data == 256 + 0x0e){
                fifo32_put(&task_console->fifo, 8 + 256);
            }
            continue;
       }
       ~略~
    }
}

2. 記号・小文字入力

 シフトキーの状態を保持する変数を作り、その値によって表示するキーデータを変えます。本では keytable0keytable1 で2つの配列を作っていたのですが、多次元配列の方が扱いやすいだろうということでちょっと構造を変えました。

// 飛んできたデータとキー文字の対応表
char keytable[2][0x80] = {
    {
        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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, '_', 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0
    },
    {
        0, 0, '!', 0x22, '#', '$', '%', '&', 0x27, '(', ')', '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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0x5c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0
    }
};

これでコンソール(とりあえず見た目だけ)完成です。

まとめ

 ついにコンソールですね〜!ちょっとウィンドウがあるだけでもそれっぽいです。
 今回は見た目と入力機能を強化したので、次回以降は多分コマンドの実装だと思います。頑張ります。