1abe3a6eaShanjiezhou use core::{
2abe3a6eaShanjiezhou intrinsics::unlikely,
3abe3a6eaShanjiezhou sync::atomic::{AtomicI32, Ordering},
4abe3a6eaShanjiezhou };
5abe3a6eaShanjiezhou
691e9d4abSLoGin use system_error::SystemError;
791e9d4abSLoGin
891e9d4abSLoGin use crate::driver::{
952da9a59SGnoCiYeH serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager,
10abe3a6eaShanjiezhou };
11abe3a6eaShanjiezhou
12abe3a6eaShanjiezhou use super::textui::{
13abe3a6eaShanjiezhou FontColor, LineId, LineIndex, TextuiCharChromatic, TEXTUI_CHAR_HEIGHT, TEXTUI_CHAR_WIDTH,
14abe3a6eaShanjiezhou };
15abe3a6eaShanjiezhou
16abe3a6eaShanjiezhou pub static TRUE_LINE_NUM: AtomicI32 = AtomicI32::new(0);
17abe3a6eaShanjiezhou pub static CHAR_PER_LINE: AtomicI32 = AtomicI32::new(0);
18abe3a6eaShanjiezhou /// textui 未初始化时直接向缓冲区写,不使用虚拟行
19abe3a6eaShanjiezhou pub static NO_ALLOC_OPERATIONS_LINE: AtomicI32 = AtomicI32::new(0);
20abe3a6eaShanjiezhou pub static NO_ALLOC_OPERATIONS_INDEX: AtomicI32 = AtomicI32::new(0);
21abe3a6eaShanjiezhou
22abe3a6eaShanjiezhou /// 当系统刚启动的时候,由于内存管理未初始化,而texiui需要动态内存分配。因此只能暂时暴力往屏幕(video_frame_buffer_info)输出信息
textui_init_no_alloc(video_enabled: bool)231a72a751SLoGin pub fn textui_init_no_alloc(video_enabled: bool) {
241a72a751SLoGin if video_enabled {
251496ba7bSLoGin let height = video_refresh_manager().device_buffer().height();
261496ba7bSLoGin let width = video_refresh_manager().device_buffer().width();
271496ba7bSLoGin TRUE_LINE_NUM.store((height / TEXTUI_CHAR_HEIGHT) as i32, Ordering::SeqCst);
28abe3a6eaShanjiezhou
291496ba7bSLoGin CHAR_PER_LINE.store((width / TEXTUI_CHAR_WIDTH) as i32, Ordering::SeqCst);
30abe3a6eaShanjiezhou }
311a72a751SLoGin }
32abe3a6eaShanjiezhou
next_line()33bde4a334S曾俊 fn next_line() {
34bde4a334S曾俊 NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst);
35bde4a334S曾俊 NO_ALLOC_OPERATIONS_LINE.fetch_add(1, Ordering::SeqCst);
36bde4a334S曾俊 if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) >= TRUE_LINE_NUM.load(Ordering::SeqCst) {
37bde4a334S曾俊 NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst);
38bde4a334S曾俊 }
39bde4a334S曾俊 }
40bde4a334S曾俊
no_init_textui_putchar_window( character: char, frcolor: FontColor, bkcolor: FontColor, is_put_to_window: bool, ) -> Result<(), SystemError>41abe3a6eaShanjiezhou pub fn no_init_textui_putchar_window(
42abe3a6eaShanjiezhou character: char,
43abe3a6eaShanjiezhou frcolor: FontColor,
44abe3a6eaShanjiezhou bkcolor: FontColor,
45abe3a6eaShanjiezhou is_put_to_window: bool,
46abe3a6eaShanjiezhou ) -> Result<(), SystemError> {
47abe3a6eaShanjiezhou //字符'\0'代表ASCII码表中的空字符,表示字符串的结尾
48abe3a6eaShanjiezhou if unlikely(character == '\0') {
49abe3a6eaShanjiezhou return Ok(());
50abe3a6eaShanjiezhou }
51a03c4f9dSLoGin send_to_default_serial8250_port(&[character as u8]);
52abe3a6eaShanjiezhou
53bde4a334S曾俊 if is_put_to_window {
54bde4a334S曾俊 match character {
55abe3a6eaShanjiezhou // 进行换行操作
56bde4a334S曾俊 '\n' => {
57*bd70d2d1SLoGin send_to_default_serial8250_port(b"\r");
58b5b571e0SLoGin if is_put_to_window {
59bde4a334S曾俊 next_line();
60abe3a6eaShanjiezhou }
61abe3a6eaShanjiezhou }
62abe3a6eaShanjiezhou // 输出制表符
63bde4a334S曾俊 '\t' => {
64abe3a6eaShanjiezhou let char = TextuiCharChromatic::new(Some(' '), frcolor, bkcolor);
65abe3a6eaShanjiezhou //打印的空格数(注意将每行分成一个个表格,每个表格为8个字符)
66abe3a6eaShanjiezhou let mut space_to_print = 8 - NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst) % 8;
67abe3a6eaShanjiezhou while space_to_print > 0 {
68abe3a6eaShanjiezhou char.no_init_textui_render_chromatic(
69abe3a6eaShanjiezhou LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
70abe3a6eaShanjiezhou LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
71abe3a6eaShanjiezhou );
72abe3a6eaShanjiezhou NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
73abe3a6eaShanjiezhou space_to_print -= 1;
74abe3a6eaShanjiezhou }
75abe3a6eaShanjiezhou }
76abe3a6eaShanjiezhou // 字符 '\x08' 代表 ASCII 码中的退格字符。它在输出中的作用是将光标向左移动一个位置,并在该位置上输出后续的字符,从而实现字符的删除或替换。
77bde4a334S曾俊 '\x08' => {
78abe3a6eaShanjiezhou NO_ALLOC_OPERATIONS_INDEX.fetch_sub(1, Ordering::SeqCst);
79abe3a6eaShanjiezhou let op_char = NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst);
80abe3a6eaShanjiezhou if op_char >= 0 {
81abe3a6eaShanjiezhou let char = TextuiCharChromatic::new(Some(' '), frcolor, bkcolor);
82abe3a6eaShanjiezhou char.no_init_textui_render_chromatic(
83abe3a6eaShanjiezhou LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
84abe3a6eaShanjiezhou LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
85abe3a6eaShanjiezhou );
86abe3a6eaShanjiezhou
87abe3a6eaShanjiezhou NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
88abe3a6eaShanjiezhou }
89abe3a6eaShanjiezhou // 需要向上缩一行
90abe3a6eaShanjiezhou if op_char < 0 {
91abe3a6eaShanjiezhou // 上缩一行
92abe3a6eaShanjiezhou NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst);
93abe3a6eaShanjiezhou NO_ALLOC_OPERATIONS_LINE.fetch_sub(1, Ordering::SeqCst);
94abe3a6eaShanjiezhou
95abe3a6eaShanjiezhou if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) < 0 {
96abe3a6eaShanjiezhou NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst);
97abe3a6eaShanjiezhou }
98abe3a6eaShanjiezhou }
99abe3a6eaShanjiezhou }
100abe3a6eaShanjiezhou // 输出其他字符
101bde4a334S曾俊 _ => {
102abe3a6eaShanjiezhou let char = TextuiCharChromatic::new(Some(character), frcolor, bkcolor);
103abe3a6eaShanjiezhou
104bde4a334S曾俊 if NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)
105bde4a334S曾俊 == CHAR_PER_LINE.load(Ordering::SeqCst)
106abe3a6eaShanjiezhou {
107bde4a334S曾俊 next_line();
108abe3a6eaShanjiezhou }
109bde4a334S曾俊
110abe3a6eaShanjiezhou char.no_init_textui_render_chromatic(
111abe3a6eaShanjiezhou LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
112abe3a6eaShanjiezhou LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
113abe3a6eaShanjiezhou );
114abe3a6eaShanjiezhou
115abe3a6eaShanjiezhou NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
116abe3a6eaShanjiezhou }
117bde4a334S曾俊 }
118bde4a334S曾俊 }
119abe3a6eaShanjiezhou return Ok(());
120abe3a6eaShanjiezhou }
121