6. aCore - 繼續完善字符輸出程序
2020-05-14
在Rust 中, 我們都習慣用 writeln! write! panic! 等等的macro 作為字串流的後處理
那麼, 在no_std
中, 也是可以享用這些Rust 的特性的。
在vga_buffer.rs
中加入
use core::fmt; //建議放第一行
impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_string(s);
Ok(())
}
}
把 print_something()
改寫成 :
pub fn print_something() {
use core::fmt::Write;
let mut writer = Writer {
column_position: 0,
color_code: ColorCode::new(Color::Yellow, Color::Black),
buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
};
writer.write_byte(b'H');
writer.write_string("ello! ");
write!(writer, "The numbers are {} and {}", 42, 1.0/3.0).unwrap();
}
然而這次我們再打開, 就發現... QEMU 不斷重啟了...
如果出現這個情況, 可能是你的 json 檔案寫錯了。檢查一下 , 修好之後要記得先 cargo clean
到現在為止, build 和xbuild 都不能按照這個檔案自動刪除舊緩存。
小插曲, 為了減少一個warning, 我把項目中的aCore 改名為 a_core
你可以修改Cargo.toml
, 設 name = "a_core"
。
然後 , 運行方法以後改成 qemu-system-x86_64 -drive format=raw,file=target/x86_64-aCore/debug/bootimage-a_core.bin
Newlines
回到Writer 把Newline 完成
先寫一個叫 clear_row 的function
impl Writer {
fn new_line(&mut self) {
for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH {
let character = self.buffer.chars[row][col].read();
self.buffer.chars[row - 1][col].write(character);
}
}
self.clear_row(BUFFER_HEIGHT - 1);
self.column_position = 0;
}
fn clear_row(&mut self, row: usize) {
let blank = ScreenChar {
ascii_character: b' ',
color_code: self.color_code,
};
for col in 0..BUFFER_WIDTH {
self.buffer.chars[row][col].write(blank);
}
}
}
原理是 : 把每一格文字都移上一列, 然後把最下面的一行清空。
清空時我們用一個 clear_row
, 方法是在每一格寫入 b''
結果如上