「30日でできる!OS自作入門」をRustで。14日目

Posted on July 1, 2019 , Tags: OS自作入門, OS, Rust

「30日でできる!OS自作入門 」のC言語の部分をできるだけRustですすめてみる。今回は14日目の内容。

解像度の変更

画面を高解像度にする。アセンブリ言語での処理になるので、ほぼ本の通りすすめる。

実行結果

以下の通り、高解像度で表示されることが確認できた。

高解像度モード

できたものの、以降、一旦320x200にもどして(VBEMODE EQU 0x104として)すすめる。

キーボード入力の文字表示

現在キーボード入力は入力された値をそのまま表示するようになっている。
これを例えばAを打鍵したらAが表示されるようにする。
キーボードまわりの処理をまとめたkeyboard.rsを新たに作り、そちらにキーボード入力値と文字の対応をもつようにする。

この配列を使って、画面に文字を表示するようにする

// lib.rs
#[no_mangle]
#[start]
pub extern "C" fn haribote_os() {
    // 省略

    // カーソル
    let min_cursor_x = 8;
    let max_cursor_x = 144;
    let mut cursor_x = min_cursor_x;
    let mut cursor_c = Color::White;

    loop {
        cli();
        if FIFO_BUF.lock().status() != 0 {
            let i = FIFO_BUF.lock().get().unwrap();
            sti();
            if KEYBOARD_OFFSET <= i && i <= 511 {
                let key = i - KEYBOARD_OFFSET;
                write_with_bg!(
                    sheet_manager,
                    shi_bg,
                    buf_bg_addr,
                    *SCREEN_WIDTH as isize,
                    *SCREEN_HEIGHT as isize,
                    0,
                    0,
                    Color::White,
                    Color::DarkCyan,
                    2,
                    "{:x}",
                    key
                );
                if key < KEYTABLE.len() as u32 {
                    // ウィンドウのテキスト領域内に表示
                    if KEYTABLE[key as usize] != 0 && cursor_x < max_cursor_x {
                        write_with_bg!(
                            sheet_manager,
                            shi_win,
                            buf_win_addr,
                            160,
                            52,
                            cursor_x,
                            28,
                            Color::Black,
                            Color::White,
                            1,
                            "{}",
                            KEYTABLE[key as usize] as char,
                        );
                        cursor_x += 8;
                    }
                    // バックスペースの場合は空白を表示してカーソルをもどす
                    if key == 0x0e && cursor_x > min_cursor_x {
                        write_with_bg!(
                            sheet_manager,
                            shi_win,
                            buf_win_addr,
                            160,
                            52,
                            cursor_x,
                            28,
                            Color::Black,
                            Color::White,
                            1,
                            " "
                        );
                        cursor_x -= 8;
                    }
                    boxfill(buf_win_addr, 160, cursor_c, cursor_x, 28, cursor_x + 8, 43);
                    sheet_manager.refresh(shi_win, cursor_x as i32, 28, cursor_x as i32 + 8, 44);
        // 省略
        // カーソル表示部分
            } else {
                if i != 0 {
                    TIMER_MANAGER.lock().init_timer(timer_index3, 0);
                    cursor_c = Color::Black;
                } else {
                    TIMER_MANAGER.lock().init_timer(timer_index3, 1);
                    cursor_c = Color::White;
                }
                TIMER_MANAGER.lock().set_time(timer_index3, 50);
                boxfill(buf_win_addr, 160, cursor_c, cursor_x, 28, cursor_x + 8, 43);
                sheet_manager.refresh(shi_win, cursor_x as i32, 28, cursor_x as i32 + 8, 44)
            }

カウンター表示をなくしたので、stlhltでループをまわすのをやめている。
カウンターを表示していたウィンドウを使い、入力された文字を表示するようにした。

実行結果

以下のように文字の入力、削除ができるようになった。

文字入力

ウィンドウの移動ができるようにする

マウス入力のハンドリング時に左クリックがおされていたらウィンドウが追従するようにする。

以前まではslide_by_diffという相対位置から絶対位置を計算して移動する関数を作っていたが、get_new_pointで絶対値の計算するように分割した。

実行結果

以下の通り、マウスの動きにあわせてウィンドウが動くことが確認できた。

ウィンドウの移動

14日目は以上となる。ここまでの内容のコードはyoshitsugu/hariboteos_in_rustのday14としてタグを打ってある。