use core::{ intrinsics::unlikely, sync::atomic::{AtomicI32, Ordering}, }; use crate::{ driver::uart::uart::{c_uart_send, UartPort}, include::bindings::bindings::video_frame_buffer_info, syscall::SystemError, }; use super::textui::{ FontColor, LineId, LineIndex, TextuiCharChromatic, TEXTUI_CHAR_HEIGHT, TEXTUI_CHAR_WIDTH, }; pub static TRUE_LINE_NUM: AtomicI32 = AtomicI32::new(0); pub static CHAR_PER_LINE: AtomicI32 = AtomicI32::new(0); /// textui 未初始化时直接向缓冲区写,不使用虚拟行 pub static NO_ALLOC_OPERATIONS_LINE: AtomicI32 = AtomicI32::new(0); pub static NO_ALLOC_OPERATIONS_INDEX: AtomicI32 = AtomicI32::new(0); /// 当系统刚启动的时候,由于内存管理未初始化,而texiui需要动态内存分配。因此只能暂时暴力往屏幕(video_frame_buffer_info)输出信息 pub fn textui_init_no_alloc() { TRUE_LINE_NUM.store( unsafe { (video_frame_buffer_info.height / TEXTUI_CHAR_HEIGHT) as i32 }, Ordering::SeqCst, ); CHAR_PER_LINE.store( unsafe { (video_frame_buffer_info.width / TEXTUI_CHAR_WIDTH) as i32 }, Ordering::SeqCst, ); } pub fn no_init_textui_putchar_window( character: char, frcolor: FontColor, bkcolor: FontColor, is_put_to_window: bool, ) -> Result<(), SystemError> { if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) > TRUE_LINE_NUM.load(Ordering::SeqCst) { NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst); } //字符'\0'代表ASCII码表中的空字符,表示字符串的结尾 if unlikely(character == '\0') { return Ok(()); } c_uart_send(UartPort::COM1.to_u16(), character as u8); // 进行换行操作 if unlikely(character == '\n') { // 换行时还需要输出\r c_uart_send(UartPort::COM1.to_u16(), b'\r'); if is_put_to_window == true { NO_ALLOC_OPERATIONS_LINE.fetch_add(1, Ordering::SeqCst); NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst); } return Ok(()); } // 输出制表符 else if character == '\t' { if is_put_to_window == true { let char = TextuiCharChromatic::new(Some(' '), frcolor, bkcolor); //打印的空格数(注意将每行分成一个个表格,每个表格为8个字符) let mut space_to_print = 8 - NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst) % 8; while space_to_print > 0 { char.no_init_textui_render_chromatic( LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)), LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)), ); NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst); space_to_print -= 1; } return Ok(()); } } // 字符 '\x08' 代表 ASCII 码中的退格字符。它在输出中的作用是将光标向左移动一个位置,并在该位置上输出后续的字符,从而实现字符的删除或替换。 else if character == '\x08' { if is_put_to_window == true { NO_ALLOC_OPERATIONS_INDEX.fetch_sub(1, Ordering::SeqCst); let op_char = NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst); if op_char >= 0 { let char = TextuiCharChromatic::new(Some(' '), frcolor, bkcolor); char.no_init_textui_render_chromatic( LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)), LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)), ); NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst); } // 需要向上缩一行 if op_char < 0 { // 上缩一行 NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst); NO_ALLOC_OPERATIONS_LINE.fetch_sub(1, Ordering::SeqCst); if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) < 0 { NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst); } } } } else { if is_put_to_window == true { // 输出其他字符 let char = TextuiCharChromatic::new(Some(character), frcolor, bkcolor); if NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst) == CHAR_PER_LINE.load(Ordering::SeqCst) { NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst); NO_ALLOC_OPERATIONS_LINE.fetch_add(1, Ordering::SeqCst); } char.no_init_textui_render_chromatic( LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)), LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)), ); NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst); } } return Ok(()); }