?? console.c.bak
字號:
//// 光標上移一行(ri - reverse line feed 反向換行)。static voidri (void){// 如果光標不在第1 行上,則直接修改光標當前行標量y--,并調整光標對應顯示內存位置pos,減去// 屏幕上一行字符所對應的內存長度字節數。 if (y > top) { y--; pos -= video_size_row; return; }// 否則需要將屏幕內容下移一行。 scrdown ();}// 光標回到第1 列(0 列)左端(cr - carriage return 回車)。static voidcr (void){// 光標所在的列號*2 即0 列到光標所在列對應的內存字節長度。 pos -= x << 1; x = 0;}// 擦除光標前一字符(用空格替代)(del - delete 刪除)。static voiddel (void){// 如果光標沒有處在0 列,則將光標對應內存位置指針pos 后退2 字節(對應屏幕上一個字符),然后// 將當前光標變量列值減1,并將光標所在位置字符擦除。 if (x) { pos -= 2; x--; *(unsigned short *) pos = video_erase_char; }}//// 刪除屏幕上與光標位置相關的部分,以屏幕為單位。csi - 控制序列引導碼(Control Sequence// Introducer)。// ANSI 轉義序列:'ESC [sJ'(s = 0 刪除光標到屏幕底端;1 刪除屏幕開始到光標處;2 整屏刪除)。// 參數:par - 對應上面s。static voidcsi_J (int par){ long count; //__asm__ ("cx") // 設為寄存器變量。 long start; //__asm__ ("di")// 首先根據三種情況分別設置需要刪除的字符數和刪除開始的顯示內存位置。 switch (par) { case 0: /* erase from cursor to end of display *//* 擦除光標到屏幕底端 */ count = (scr_end - pos) >> 1; start = pos; break; case 1: /* erase from start to cursor *//* 刪除從屏幕開始到光標處的字符 */ count = (pos - origin) >> 1; start = origin; break; case 2: /* erase whole display *//* 刪除整個屏幕上的字符 */ count = video_num_columns * video_num_lines; start = origin; break; default: return; }// 然后使用擦除字符填寫刪除字符的地方。// %0 - ecx(要刪除的字符數count);%1 - edi(刪除操作開始地址);%2 - eax(填入的擦除字符)。 _asm { pushf
mov ecx,count;
mov edi,start;
mov ax,video_erase_char;
cld;
rep stosw; popf
}
// __asm__ ("cld\n\t" "rep\n\t" "stosw\n\t"::"c" (count), "D" (start), "a" (video_erase_char):"cx", "di");}//// 刪除行內與光標位置相關的部分,以一行為單位。// ANSI 轉義字符序列:'ESC [sK'(s = 0 刪除到行尾;1 從開始刪除;2 整行都刪除)。static voidcsi_K (int par){ long count; //__asm__ ("cx") // 設置寄存器變量。 long start; //__asm__ ("di")// 首先根據三種情況分別設置需要刪除的字符數和刪除開始的顯示內存位置。 switch (par) { case 0: /* erase from cursor to end of line *//* 刪除光標到行尾字符 */ if (x >= video_num_columns) return; count = video_num_columns - x; start = pos; break; case 1: /* erase from start of line to cursor *//* 刪除從行開始到光標處 */ start = pos - (x << 1); count = (x < video_num_columns) ? x : video_num_columns; break; case 2: /* erase whole line *//* 將整行字符全刪除 */ start = pos - (x << 1); count = video_num_columns; break; default: return; }// 然后使用擦除字符填寫刪除字符的地方。// %0 - ecx(要刪除的字符數count);%1 - edi(刪除操作開始地址);%2 - eax(填入的擦除字符)。 _asm { pushf
mov ecx,count;
mov edi,start;
mov ax,video_erase_char;
cld;
rep stosw; popf
}
// __asm__ ("cld\n\t" "rep\n\t" "stosw\n\t"::"c" (count), "D" (start), "a" (video_erase_char):"cx", "di");}//// 允許翻譯(重顯)(允許重新設置字符顯示方式,比如加粗、加下劃線、閃爍、反顯等)。// ANSI 轉義字符序列:'ESC [nm'。n = 0 正常顯示;1 加粗;4 加下劃線;7 反顯;27 正常顯示。voidcsi_m (void){ unsigned int i; for (i = 0; i <= npar; i++) switch (par[i]) { case 0: attr = 0x07; break; case 1: attr = 0x0f; break; case 4: attr = 0x0f; break; case 7: attr = 0x70; break; case 27: attr = 0x07; break; }}//// 根據設置顯示光標。// 根據顯示內存光標對應位置pos,設置顯示控制器光標的顯示位置。static _inline voidset_cursor (void){ cli ();// 首先使用索引寄存器端口選擇顯示控制數據寄存器r14(光標當前顯示位置高字節),然后寫入光標// 當前位置高字節(向右移動9 位表示高字節移到低字節再除以2)。是相對于默認顯示內存操作的。 outb_p (14, video_port_reg); outb_p ((unsigned char)(0xff & ((pos - video_mem_start) >> 9)), video_port_val);// 再使用索引寄存器選擇r15,并將光標當前位置低字節寫入其中。 outb_p (15, video_port_reg); outb_p ((unsigned char)(0xff & ((pos - video_mem_start) >> 1)), video_port_val); sti ();}//// 發送對終端VT100 的響應序列。// 將響應序列放入讀緩沖隊列中。static voidrespond (struct tty_struct *tty){ char *p = RESPONSE; cli (); // 關中斷。 while (*p) { // 將字符序列放入寫隊列。 PUTCH (*p, tty->read_q); p++; } sti (); // 開中斷。 copy_to_cooked (tty); // 轉換成規范模式(放入輔助隊列中)。}//// 在光標處插入一空格字符。static voidinsert_char (void){ unsigned long i = x; unsigned short tmp, old = video_erase_char; unsigned short *p = (unsigned short *) pos;// 光標開始的所有字符右移一格,并將擦除字符插入在光標所在處。// 若一行上都有字符的話,則行最后一個字符將不會更動?? while (i++ < video_num_columns) { tmp = *p; *p = old; old = tmp; p++; }}//// 在光標處插入一行(則光標將處在新的空行上)。// 將屏幕從光標所在行到屏幕底向下卷動一行。static voidinsert_line (void){ int oldtop, oldbottom; oldtop = top; // 保存原top,bottom 值。 oldbottom = bottom; top = y; // 設置屏幕卷動開始行。 bottom = video_num_lines; // 設置屏幕卷動最后行。 scrdown (); // 從光標開始處,屏幕內容向下滾動一行。 top = oldtop; // 恢復原top,bottom 值。 bottom = oldbottom;}//// 刪除光標處的一個字符。static voiddelete_char (void){ unsigned long i; unsigned short *p = (unsigned short *) pos;// 如果光標超出屏幕最右列,則返回。 if (x >= video_num_columns) return;// 從光標右一個字符開始到行末所有字符左移一格。 i = x; while (++i < video_num_columns) { *p = *(p + 1); p++; }// 最后一個字符處填入擦除字符(空格字符)。 *p = video_erase_char;}//// 刪除光標所在行。// 從光標所在行開始屏幕內容上卷一行。static voiddelete_line (void){ int oldtop, oldbottom; oldtop = top; // 保存原top,bottom 值。 oldbottom = bottom; top = y; // 設置屏幕卷動開始行。 bottom = video_num_lines; // 設置屏幕卷動最后行。 scrup (); // 從光標開始處,屏幕內容向上滾動一行。 top = oldtop; // 恢復原top,bottom 值。 bottom = oldbottom;}//// 在光標處插入nr 個字符。// ANSI 轉義字符序列:'ESC [n@ '。// 參數 nr = 上面n。static voidcsi_at (unsigned int nr){// 如果插入的字符數大于一行字符數,則截為一行字符數;若插入字符數nr 為0,則插入1 個字符。 if (nr > video_num_columns) nr = video_num_columns; else if (!nr) nr = 1;// 循環插入指定的字符數。 while (nr--) insert_char ();}//// 在光標位置處插入nr 行。// ANSI 轉義字符序列'ESC [nL'。static voidcsi_L (unsigned int nr){// 如果插入的行數大于屏幕最多行數,則截為屏幕顯示行數;若插入行數nr 為0,則插入1 行。 if (nr > video_num_lines) nr = video_num_lines; else if (!nr) nr = 1;// 循環插入指定行數nr。 while (nr--) insert_line ();}//// 刪除光標處的nr 個字符。// ANSI 轉義序列:'ESC [nP'。static voidcsi_P (unsigned int nr){// 如果刪除的字符數大于一行字符數,則截為一行字符數;若刪除字符數nr 為0,則刪除1 個字符。 if (nr > video_num_columns) nr = video_num_columns; else if (!nr) nr = 1;// 循環刪除指定字符數nr。 while (nr--) delete_char ();}//// 刪除光標處的nr 行。// ANSI 轉義序列:'ESC [nM'。static voidcsi_M (unsigned int nr){// 如果刪除的行數大于屏幕最多行數,則截為屏幕顯示行數;若刪除的行數nr 為0,則刪除1 行。 if (nr > video_num_lines) nr = video_num_lines; else if (!nr) nr = 1;// 循環刪除指定行數nr。 while (nr--) delete_line ();}static int saved_x = 0; // 保存的光標列號。static int saved_y = 0; // 保存的光標行號。//// 保存當前光標位置。static voidsave_cur (void){ saved_x = x; saved_y = y;}//// 恢復保存的光標位置。static voidrestore_cur (void){ gotoxy (saved_x, saved_y);}//// 控制臺寫函數。// 從終端對應的tty 寫緩沖隊列中取字符,并顯示在屏幕上。voidcon_write (struct tty_struct *tty){ int nr; char c;// 首先取得寫緩沖隊列中現有字符數nr,然后針對每個字符進行處理。 nr = CHARS (tty->write_q); while (nr--) {// 從寫隊列中取一字符c,根據前面所處理字符的狀態state 分別處理。狀態之間的轉換關系為:// state = 0:初始狀態;或者原是狀態4;或者原是狀態1,但字符不是'[';// 1:原是狀態0,并且字符是轉義字符ESC(0x1b = 033 = 27);// 2:原是狀態1,并且字符是'[';// 3:原是狀態2;或者原是狀態3,并且字符是';'或數字。// 4:原是狀態3,并且字符不是';'或數字; GETCH (tty->write_q, c); switch (state) { case 0:// 如果字符不是控制字符(c>31),并且也不是擴展字符(c<127),則 if (c > 31 && c < 127) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -