日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第17天 命令行窗口

發(fā)布時(shí)間:2024/3/13 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第17天 命令行窗口 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

第17天 命令行窗口

2020.4.19

1. 閑置任務(wù)(harib14a)

  • 在harib13e中,如果任務(wù)B0~B2沒有啟動(dòng),只有任務(wù)A啟動(dòng),當(dāng)任務(wù)A進(jìn)入休眠狀態(tài),程序就會因?yàn)檎也坏狡渌娜蝿?wù)而導(dǎo)致運(yùn)行出現(xiàn)異常。

    • 在harib13e的bootpack.c的HariMain中將代碼:task_run(task_b[i], 2, i + 1); 注釋掉。
    • make后用VMware運(yùn)行:
  • 當(dāng)出現(xiàn)上面的情況的時(shí)候,最好的辦法就是讓CPU執(zhí)行HLT休息。

  • 讓HLT成為一個(gè)任務(wù),放在最下層的LEVEL中。 這樣,即便任務(wù)A進(jìn)入休眠狀態(tài),CPU也會切換到這個(gè)HLT任務(wù),這樣就不會因?yàn)檎也坏饺蝿?wù)而出錯(cuò)了。這個(gè)HLT任務(wù),美名其曰:閑置任務(wù)(idle task)

    • 閑置任務(wù)task_idle(mtask.c中):void task_idle(void) {for (;;) {io_hlt();} }
    • 這個(gè)閑置任務(wù)其實(shí)就是"哨兵"。
  • 修改task_init,將閑置任務(wù)放到最底層LEVEL即可:

    struct TASK *task_init(struct MEMMAN *memman) {int i;struct TASK *task, *idle;……idle = task_alloc();idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;idle->tss.eip = (int) &task_idle;idle->tss.es = 1 * 8;idle->tss.cs = 2 * 8;idle->tss.ss = 1 * 8;idle->tss.ds = 1 * 8;idle->tss.fs = 1 * 8;idle->tss.gs = 1 * 8;task_run(idle, MAX_TASKLEVELS - 1, 1); /*priority=1*/return task; }
  • 修改HariMain,將代碼task_run(task_b[i], 2, i + 1);注釋掉。然后make并在VMware上運(yùn)行:

    • 沒有出現(xiàn)錯(cuò)誤,順利運(yùn)行。

2. 創(chuàng)建命令行窗口(harib14b)

  • 命令行窗口不屬于任務(wù)A,而是作為一個(gè)新的任務(wù)獨(dú)立存在。將任務(wù)B稍加修改就可以創(chuàng)建命令行窗口了。

  • 修改HariMain:

    void HariMain(void) {……/* sht_cons */sht_cons = sheet_alloc(shtctl);buf_cons = (unsigned char *) memman_alloc_4k(memman, 256 * 165);sheet_setbuf(sht_cons, buf_cons, 256, 165, -1); make_window8(buf_cons, 256, 165, "console", 0);make_textbox8(sht_cons, 8, 28, 240, 128, COL8_000000);task_cons = task_alloc();task_cons->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8;task_cons->tss.eip = (int) &console_task;task_cons->tss.es = 1 * 8;task_cons->tss.cs = 2 * 8;task_cons->tss.ss = 1 * 8;task_cons->tss.ds = 1 * 8;task_cons->tss.fs = 1 * 8;task_cons->tss.gs = 1 * 8;*((int *) (task_cons->tss.esp + 4)) = (int) sht_cons;task_run(task_cons, 2, 2); /* level=2, priority=2 */……sheet_slide(sht_back, 0, 0);sheet_slide(sht_cons, 32, 4);sheet_slide(sht_win, 64, 56);sheet_slide(sht_mouse, mx, my);sheet_updown(sht_back, 0);sheet_updown(sht_cons, 1);sheet_updown(sht_win, 2);sheet_updown(sht_mouse, 3);…… }
  • 添加命令行任務(wù)console_task:

    void console_task(struct SHEET *sheet) {struct FIFO32 fifo;struct TIMER *timer;struct TASK *task = task_now(); /*獲取當(dāng)前命令行任務(wù)*/int i, fifobuf[128], cursor_x = 8, cursor_c = COL8_000000;fifo32_init(&fifo, 128, fifobuf, task);timer = timer_alloc();timer_init(timer, &fifo, 1);timer_settime(timer, 50);for (;;) {io_cli();if (fifo32_status(&fifo) == 0) {task_sleep(task); /*命令行任務(wù)休眠*/io_sti();} else {i = fifo32_get(&fifo);io_sti();if (i <= 1) { /* 光標(biāo)定時(shí)器 */if (i != 0) {timer_init(timer, &fifo, 0); cursor_c = COL8_FFFFFF;} else {timer_init(timer, &fifo, 1);cursor_c = COL8_000000;}timer_settime(timer, 50);boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);sheet_refresh(sheet, cursor_x, 28, cursor_x + 8, 44);}}} }
    • 每一個(gè)任務(wù)都有一個(gè)自己的FIFO緩沖區(qū)。
    • 命令行任務(wù)需要休眠,當(dāng)執(zhí)行到console_task時(shí),說明正在CPU上運(yùn)行的是命令行任務(wù),因此可以通過task_now函數(shù)獲取命令行任務(wù)本身
  • make后在VMware上運(yùn)行:

    • 命令行窗口的雛形做好了!

3. 切換輸入窗口(harib14c)

  • harib14b中,無論如何輸入字符,都是在task_a中輸入。現(xiàn)在,需要解決的問題是:向命令行窗口輸入字符。

  • 向命令行窗口輸入字符,首先要選中命令行窗口。使用Tab鍵在命令行窗口和任務(wù)A之間切換

  • 切換窗口:先暫時(shí)將窗口標(biāo)題欄的顏色改一改。也就是,當(dāng)按Tab時(shí),命令行窗口和任務(wù)A的窗口標(biāo)題欄的顏色發(fā)生變化。(以此來告訴用戶選中了那個(gè)窗口)

  • harib14b中的make_window8函數(shù)完成了兩個(gè)功能:1.描繪窗口標(biāo)題欄;2.描繪窗口剩余部分。

  • 將make_window8函數(shù)改寫一下,將描繪標(biāo)題欄的部分獨(dú)立出來形成一個(gè)新的函數(shù)make_wtitle8。:

    void make_window8(unsigned char *buf, int xsize, int ysize, char *title, char act) {boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, xsize - 1, 0 );boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, xsize - 2, 1 );boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, 0, ysize - 1);boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, 1, ysize - 2);boxfill8(buf, xsize, COL8_848484, xsize - 2, 1, xsize - 2, ysize - 2);boxfill8(buf, xsize, COL8_000000, xsize - 1, 0, xsize - 1, ysize - 1);boxfill8(buf, xsize, COL8_C6C6C6, 2, 2, xsize - 3, ysize - 3);boxfill8(buf, xsize, COL8_848484, 1, ysize - 2, xsize - 2, ysize - 2);boxfill8(buf, xsize, COL8_000000, 0, ysize - 1, xsize - 1, ysize - 1);make_wtitle8(buf, xsize, title, act);return; }void make_wtitle8(unsigned char *buf, int xsize, char *title, char act) {static char closebtn[14][16] = {"OOOOOOOOOOOOOOO@","OQQQQQQQQQQQQQ$@","OQQQQQQQQQQQQQ$@","OQQQ@@QQQQ@@QQ$@","OQQQQ@@QQ@@QQQ$@","OQQQQQ@@@@QQQQ$@","OQQQQQQ@@QQQQQ$@","OQQQQQ@@@@QQQQ$@","OQQQQ@@QQ@@QQQ$@","OQQQ@@QQQQ@@QQ$@","OQQQQQQQQQQQQQ$@","OQQQQQQQQQQQQQ$@","O$$$$$$$$$$$$$$@","@@@@@@@@@@@@@@@@"};int x, y;char c, tc, tbc;if (act != 0) {tc = COL8_FFFFFF;tbc = COL8_000084;} else {tc = COL8_C6C6C6;tbc = COL8_848484;}boxfill8(buf, xsize, tbc, 3, 3, xsize - 4, 20);putfonts8_asc(buf, xsize, 24, 4, tc, title);for (y = 0; y < 14; y++) {for (x = 0; x < 16; x++) {c = closebtn[y][x];if (c == '@') {c = COL8_000000;} else if (c == '$') {c = COL8_848484;} else if (c == 'Q') {c = COL8_C6C6C6;} else {c = COL8_FFFFFF;}buf[(5 + y) * xsize + (xsize - 21 + x)] = c;}}return; }
    • 當(dāng)act!=0時(shí),字體顏色白色,背景顏色是暗藍(lán)。【選中】
    • 當(dāng)act=0時(shí),字體顏色是亮灰,背景顏色是暗灰。【未選中】
  • 修改HariMain:

    void HariMain(void){……int key_to = 0;……for (;;) {io_cli();if (fifo32_status(&fifo) == 0) {……} else {i = fifo32_get(&fifo);io_sti();if (256 <= i && i <= 511) { /* 鍵盤數(shù)據(jù) */……if (i == 256 + 0x0f) { /* Tab鍵 */if (key_to == 0) {key_to = 1;make_wtitle8(buf_win, sht_win->bxsize, "task_a", 0); /*未選中task_a*/make_wtitle8(buf_cons, sht_cons->bxsize, "console", 1); /*選中命令行*/} else {key_to = 0;make_wtitle8(buf_win, sht_win->bxsize, "task_a", 1);make_wtitle8(buf_cons, sht_cons->bxsize, "console", 0);}sheet_refresh(sht_win, 0, 0, sht_win->bxsize, 21); /*刷新圖層*/sheet_refresh(sht_cons, 0, 0, sht_cons->bxsize, 21); /*刷星圖層*/}/* 重新顯示光標(biāo) */boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);} else if (512 <= i && i <= 767) { /* 鼠標(biāo)數(shù)據(jù) */……} else if (i <= 1) { /* 任務(wù)A的光標(biāo)定時(shí)器 */……}}} }
    • key_to,用于記錄鍵盤輸入的key應(yīng)該輸出到哪里(to)。
      • key_to=0:發(fā)送到任務(wù)A。
      • key_to=1: 發(fā)送到命令行窗口任務(wù)。
  • make后在VMware運(yùn)行:

    • 接下來的任務(wù)就是:根據(jù)選中的窗口進(jìn)行文本輸入。

4. 實(shí)現(xiàn)字符輸入(harib14d)

  • 實(shí)現(xiàn)向命令行窗口輸入字符,只需要在鍵盤按下的時(shí)候向console_task的FIFO緩沖區(qū)寫入數(shù)據(jù)即可。

  • 鍵盤產(chǎn)生中斷的時(shí)候,產(chǎn)生的數(shù)據(jù)是寫入HariMain的緩沖區(qū)的,這是keyboard.c中代碼’寫死’的。因此,想要向命令行窗口寫入數(shù)據(jù),在HariMain中需要獲得console_task的緩沖區(qū)。

  • 沒有哪個(gè)任務(wù)是不需要使用FIFO緩沖區(qū)的,因此,重新定義結(jié)構(gòu)體TASK:

    struct TASK {int sel, flags; int level, priority;struct FIFO32 fifo; /*緩沖區(qū)*/struct TSS32 tss; };
    • 因?yàn)樵贔IFO32的定義中就有struct TASK *task;,因此,這樣就把緩沖區(qū)和任務(wù)綁定起來了。通過任務(wù)能夠獲取緩沖區(qū),通過緩沖區(qū)能夠獲取任務(wù)。struct FIFO32 {int *buf;int p, q, size, free, flags;struct TASK *task; };
    • 類似于這樣的結(jié)構(gòu):
  • 修改HariMain:

    void HariMain(void) {……for (;;) {io_cli();if (fifo32_status(&fifo) == 0) {task_sleep(task_a);io_sti();} else {i = fifo32_get(&fifo);io_sti();if (256 <= i && i <= 511) { /* 鍵盤數(shù)據(jù) */sprintf(s, "%02X", i - 256);putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);if (i < 0x54 + 256 && keytable[i - 256] != 0) { /* 一般字符,能顯示 */if (key_to == 0) { /* 發(fā)送給任務(wù)A */if (cursor_x < 128) {/* 顯示一個(gè)字符后光標(biāo)后移1位 */s[0] = keytable[i - 256];s[1] = 0;putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, s, 1);cursor_x += 8;}} else { /* 發(fā)送給命令行窗口 */fifo32_put(&task_cons->fifo, keytable[i - 256] + 256); /*向命令行窗口的緩沖區(qū)寫入數(shù)據(jù)*/}}if (i == 256 + 0x0e) { /* 退格鍵 */if (key_to == 0) { /* 發(fā)送給任務(wù)A */if (cursor_x > 8) {putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1);cursor_x -= 8;}} else { /* 發(fā)送給命令行任務(wù) */fifo32_put(&task_cons->fifo, 8 + 256);}}if (i == 256 + 0x0f) { /* Tab */……}……} else if (512 <= i && i <= 767) { /* 鼠標(biāo)數(shù)據(jù) */……} else if (i <= 1) { /* 光標(biāo)定時(shí)器 */……}}} }
    • 當(dāng)key_to不等于0時(shí),OS會向命令行窗口發(fā)送鍵盤數(shù)據(jù),支持一般的字符和退格鍵。由于命令行窗口也使用了定時(shí)器,為了不和鍵盤數(shù)據(jù)沖突,在寫入命令行緩沖區(qū)時(shí),將數(shù)據(jù)加上256。
    • 向命令行窗口發(fā)送數(shù)據(jù)的時(shí)候,不是直接發(fā)送從鍵盤接受到的原始數(shù)據(jù),而是發(fā)送經(jīng)過keytable轉(zhuǎn)化后的值。這樣就可以省略在命令行窗口任務(wù)中將按鍵編碼轉(zhuǎn)化為字符編碼的步驟了。
    • 關(guān)于退格鍵,我們將它的字符編碼定義為8,在ASCII中,退格鍵就是8。
  • 修改console_task:

    void console_task(struct SHEET *sheet) {struct TIMER *timer;struct TASK *task = task_now();int i, fifobuf[128], cursor_x = 16, cursor_c = COL8_000000;char s[2];fifo32_init(&task->fifo, 128, fifobuf, task);timer = timer_alloc();timer_init(timer, &task->fifo, 1);timer_settime(timer, 50);/* 顯示提示符 */putfonts8_asc_sht(sheet, 8, 28, COL8_FFFFFF, COL8_000000, ">", 1);for (;;) {io_cli();if (fifo32_status(&task->fifo) == 0) {task_sleep(task);io_sti();} else {i = fifo32_get(&task->fifo);io_sti();if (i <= 1) { /* 光標(biāo)定時(shí)器 */if (i != 0) {timer_init(timer, &task->fifo, 0); cursor_c = COL8_FFFFFF;} else {timer_init(timer, &task->fifo, 1); cursor_c = COL8_000000;}timer_settime(timer, 50);}if (256 <= i && i <= 511) { /*鼠標(biāo)數(shù)據(jù)*/if (i == 8 + 256) {/* 退格鍵 */if (cursor_x > 16) {/* 不能刪去提示符 */putfonts8_asc_sht(sheet, cursor_x, 28, COL8_FFFFFF, COL8_000000, " ", 1);cursor_x -= 8;}} else {/* 堦斒一般字符暥帤 */if (cursor_x < 240) {/* 后移光標(biāo) */s[0] = i - 256;s[1] = 0;putfonts8_asc_sht(sheet, cursor_x, 28, COL8_FFFFFF, COL8_000000, s, 1);cursor_x += 8;}}}/* 重新繪制光標(biāo) */boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);sheet_refresh(sheet, cursor_x, 28, cursor_x + 8, 44);}} }
    • 在harib14c的bootpack.c的console_task函數(shù)基礎(chǔ)上,將代碼struct FIFO32 fifo;刪除,改成使用&task->fifo。
  • make后用VMware運(yùn)行:

    • 可以輸入英文字母(大寫)、數(shù)字和部分符號。無法輸入“!”和“%”等符號。

5. 符號的輸入(harib14e)

  • 實(shí)現(xiàn)輸入“!”和“%”。

  • 首先,要處理Shift鍵:

    • 輸入“!”需要按住Shift鍵輸入。
    • Shift鍵分為左右Shift,它們的按鍵編碼如下: 按鍵按下抬起
      左Shift0x2a0xaa
      右Shift0x360xb6
    • 準(zhǔn)備一個(gè)key_shift變量:
      • 初始值為0,代表左右Shift都沒按下。
      • 當(dāng)左Shift按下,key_shift=1;
      • 當(dāng)右Shift按下,key_shift=2;
      • 當(dāng)兩個(gè)都按下,key_shift=3。
    • 因此,當(dāng)key_shift為0時(shí),按照keytable0[]將按鍵編碼轉(zhuǎn)化成為字符編碼;當(dāng)key_shift不為0時(shí),按照keytable1[]進(jìn)行轉(zhuǎn)換。
  • 修改HariMain:

    void HariMain(void) {……static char keytable0[0x80] = {0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0, 0,'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0, 0, 'A', 'S','D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V','B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1','2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0x5c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0};static char keytable1[0x80] = {0, 0, '!', 0x22, '#', '$', '%', '&', 0x27, '(', ')', '~', '=', '~', 0, 0,'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '`', '{', 0, 0, 'A', 'S','D', 'F', 'G', 'H', 'J', 'K', 'L', '+', '*', 0, 0, '}', 'Z', 'X', 'C', 'V','B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1','2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, '_', 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0};int key_to = 0, key_shift = 0;……for (;;) {io_cli();if (fifo32_status(&fifo) == 0) {task_sleep(task_a);io_sti();} else {i = fifo32_get(&fifo);io_sti();if (256 <= i && i <= 511) { /* 鍵盤數(shù)據(jù) */sprintf(s, "%02X", i - 256);putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);if (i < 0x80 + 256) { /* 按鍵編碼轉(zhuǎn)化為字符編碼 */if (key_shift == 0) {s[0] = keytable0[i - 256];} else {s[0] = keytable1[i - 256];}} else { /*無法轉(zhuǎn)化的按鍵編碼*/s[0] = 0;}if (s[0] != 0) { /* 一般字符 */if (key_to == 0) { /* 發(fā)送給任務(wù)A */if (cursor_x < 128) {/* 光標(biāo)后移 */s[1] = 0;putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, s, 1);cursor_x += 8;}} else { /* 發(fā)送給命令行窗口任務(wù) */fifo32_put(&task_cons->fifo, s[0] + 256);}}if (i == 256 + 0x0e) { /* 退格鍵 */……}if (i == 256 + 0x0f) { /* Tab */……}if (i == 256 + 0x2a) { /* 左Shift ON */key_shift |= 1;}if (i == 256 + 0x36) { /* 右Shift ON */key_shift |= 2;}if (i == 256 + 0xaa) { /* 左Shfit OFF */key_shift &= ~1;}if (i == 256 + 0xb6) { /* 右Shift OFF */key_shift &= ~2;}……} else if (512 <= i && i <= 767) { /* 鼠標(biāo)數(shù)據(jù) */……} else if (i <= 1) { /* 光標(biāo)定時(shí)器 */……}}} }
    • 考慮到支持\和_的輸入,讓keytable0和keytable1支持到0x80。keytable0中對英文字母和小鍵盤的部分沒有進(jìn)行改動(dòng)。
  • make后在VMware上運(yùn)行:

    • 支持輸入“!”等需要使用Shift輸入的符號。下面需要支持小寫。

6. 大寫字母與小寫字母(harib14f)

  • 區(qū)分大小寫,需要同時(shí)判斷Shift鍵的狀態(tài)和CapsLock的狀態(tài)

    • 關(guān)系如下: CapsLockShift字母
      OFFOFF小寫
      OFFON大寫
      ONOFF大寫
      ONON小寫
    • 轉(zhuǎn)化成小寫字母的條件:
      • 輸入的字符是英文字母
      • (CapsLockON && ShiftOFF) || (CapsLockOFF && ShiftON)
    • 我們已經(jīng)獲取了Shift的狀態(tài)。CapsLock的狀態(tài)BIOS知道。現(xiàn)在是32位模式,不能訪問BIOS。還好在asmhead.nas中將BIOS的狀態(tài)保存了下來。從BIOS獲取的鍵盤狀態(tài)就保存在binfo->leds中
    • binfo->leds是char類型,一個(gè)字節(jié)。數(shù)位含義如下:
  • 修改HariMain:

    void HariMain(void) {……int key_to = 0, key_shift = 0, key_leds = (binfo->leds >> 4) & 7; /*只取binfo->leds的4~6位存入key_leds*/……for (;;) {io_cli();if (fifo32_status(&fifo) == 0) {task_sleep(task_a);io_sti();} else {i = fifo32_get(&fifo);io_sti();if (256 <= i && i <= 511) { /* 鍵盤數(shù)據(jù) */sprintf(s, "%02X", i - 256);putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);if (i < 0x80 + 256) { /* 案件編碼轉(zhuǎn)化成為字符編碼 */if (key_shift == 0) {s[0] = keytable0[i - 256];} else {s[0] = keytable1[i - 256];}} else {s[0] = 0;}if ('A' <= s[0] && s[0] <= 'Z') { /* 英文字母 */if (((key_leds & 4) == 0 && key_shift == 0) ||((key_leds & 4) != 0 && key_shift != 0)) {s[0] += 0x20; /* 轉(zhuǎn)化成小寫 */}}if (s[0] != 0) { /* 一般字符 */……}……} else if (512 <= i && i <= 767) { /* 鼠標(biāo)數(shù)據(jù) */……} else if (i <= 1) { /* 光標(biāo)定時(shí)器 */……}}} }
  • make后在VMware運(yùn)行:

    • 現(xiàn)在能夠根據(jù)CapsLock的狀態(tài)切換大小寫字母了。我們按下CapsLock,鍵盤上CapsLock的燈沒亮,輸入字符依舊是小寫。

7. 對各種鎖定鍵的支持(harib14g)

  • 鍵盤上的鎖定鍵按下時(shí)產(chǎn)生的數(shù)據(jù):

    • 0x3a:CapsLock
    • 0x45: NumLock
    • 0x46: ScrollLock
  • 當(dāng)HariMain的FIFO緩沖區(qū)接收到上述數(shù)據(jù),將binfo->leds對應(yīng)位改寫即可。 這樣就完成了鎖定鍵模式的切換。但是,只這樣做這些鎖定鍵的指示燈并不會亮起,但系統(tǒng)仍是處于CapsLock模式。

  • 點(diǎn)亮熄滅鍵盤鎖定鍵指示燈的方法:

  • 根據(jù)上述方法,修改HariMain:

    #define KEYCMD_LED 0xedvoid HariMain(void) {……struct FIFO32 fifo, keycmd;int fifobuf[128], keycmd_buf[32];……int key_to = 0, key_shift = 0, key_leds = (binfo->leds >> 4) & 7, keycmd_wait = -1;……fifo32_init(&keycmd, 32, keycmd_buf, 0);……/* 為了避免和鍵盤當(dāng)前狀態(tài)沖突,在一開始先進(jìn)行設(shè)置 */fifo32_put(&keycmd, KEYCMD_LED);fifo32_put(&keycmd, key_leds);for (;;) {if (fifo32_status(&keycmd) > 0 && keycmd_wait < 0) {/* 如果存在向鍵盤控制器發(fā)送的數(shù)據(jù),那么發(fā)送 */keycmd_wait = fifo32_get(&keycmd); /*獲取數(shù)據(jù)*/wait_KBC_sendready(); /*等待鍵盤*/io_out8(PORT_KEYDAT, keycmd_wait); /*寫入數(shù)據(jù)*/}io_cli();if (fifo32_status(&fifo) == 0) {task_sleep(task_a);io_sti();} else {i = fifo32_get(&fifo);io_sti();if (256 <= i && i <= 511) { /* 鍵盤數(shù)據(jù) */……if (i == 256 + 0x3a) { /* CapsLock */key_leds ^= 4;fifo32_put(&keycmd, KEYCMD_LED);fifo32_put(&keycmd, key_leds);}if (i == 256 + 0x45) { /* NumLock */key_leds ^= 2;fifo32_put(&keycmd, KEYCMD_LED);fifo32_put(&keycmd, key_leds);}if (i == 256 + 0x46) { /* ScrollLock */key_leds ^= 1;fifo32_put(&keycmd, KEYCMD_LED);fifo32_put(&keycmd, key_leds);}if (i == 256 + 0xfa) { /* 收到鍵盤成功接收到數(shù)據(jù)的ACK */keycmd_wait = -1;}if (i == 256 + 0xfe) { /* 收到鍵盤失敗接收到數(shù)據(jù)的ACK */wait_KBC_sendready();io_out8(PORT_KEYDAT, keycmd_wait);}……} else if (512 <= i && i <= 767) { /* 鼠標(biāo)數(shù)據(jù) */……} else if (i <= 1) { /* 光標(biāo)定時(shí)器 */……}}} }
    • 工作原理:
      • 首先,創(chuàng)建了一個(gè)叫keycmd的FIFO緩沖區(qū),這個(gè)緩沖區(qū)不是用來接收中斷產(chǎn)生的數(shù)據(jù)的,而是用來管理由任務(wù)A向鍵盤控制器發(fā)送數(shù)據(jù)的順序的。如果有數(shù)據(jù)要發(fā)送到鍵盤控制器,首先會在keycmd中積累起來。
      • keycmd_wait變量。當(dāng)keycmd_wait=-1時(shí),可以從keycmd緩沖區(qū)獲取數(shù)據(jù)寫入鍵盤控制器。keycmd_wait!=-1時(shí),代表要寫入鍵盤控制器的數(shù)據(jù)。只有接收到0xfa的ACK,keycmd才能等于-1,才能向鍵盤控制器寫入數(shù)據(jù)
      • 當(dāng)接收到0xfe的ACK,重新發(fā)送剛才發(fā)送失敗的數(shù)據(jù)。
  • make后使用VMware運(yùn)行,鎖定鍵可以使用,且指示燈能夠亮起。

8. 寫在今天

  • 為了不讓自己久坐以致腰痛難耐,我已經(jīng)琢磨出一個(gè)新的預(yù)防腰痛的學(xué)習(xí)方式:站著使用電腦和查閱書籍。
  • 現(xiàn)在是2020.4.20 17:31。
  • 今天的工作總體上來講不難,就是鎖定鍵那里有點(diǎn)晦澀。
  • 今日還沒跑步,待會兒便去。
  • 350頁了,真·50%.
  • 講一件奇怪的事情:Github上上傳的圖片突然就訪問不了了。嘗試了幾種解決方法:換瀏覽器,chrome, firefox, 360, edge都不行;讓同學(xué)用電腦訪問,不行;用自己手機(jī)QQ訪問,不行;用手機(jī)Chrome訪問不行。用手機(jī)自帶瀏覽器訪問,可以;翻墻訪問,可以。這真是太奇怪了!
  • 先不管這個(gè)奇怪吧。明天繼續(xù)加油,沖鴨!

總結(jié)

以上是生活随笔為你收集整理的第17天 命令行窗口的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。