實現乙個命令列任務,首先需要乙個命令列視窗,然後需要乙個命令列任務,在命令列任務中實現命令列的相關功能。 一、
建立乙個命令列視窗
建立命令列視窗就是在螢幕上畫個視窗出來,實際就是操作視訊記憶體,這一部分利用前面已經實現的makewindow8函式即可實現。 二、
建立乙個命令列任務
有了命令列視窗,我們再來實現命令列的功能。
(1)游標閃爍功能
在剛開始做命令行時,命令列的功能就是游標閃爍即可,也就是說命令列任務中需要乙個定時器來控制游標色塊的顏色,使之產生閃爍的效果。在harimain函式中已經實現過游標的閃爍功能,該功能還需要使用乙個
fifo
佇列,通過在佇列中存放不同的數值,可以使得游標的顏色進行變換,實現方法與
harimain
中游標閃爍的實現方法相同。
(2)切換輸入視窗
目前使用者使用鍵盤輸入資料時,所有的資料都被task_a給接收了,新建的命令列視窗完全就是個擺設,為了使得命令列視窗可以接收資料,在
harimain
中設定整型變數
key_to
,key_to=0時,
task_a
接收鍵盤資料;
key_to=1
時,命令列任務接收鍵盤資料。鍵盤資料都儲存在各任務的
fifo
中。而key_to
值的切換則是由主程式
harimain
負責監聽
tab鍵來進行切換的,同時在切換視窗的同時,視窗標題欄的顏色發生改變。
(3)實現字元輸入
只要各個任務可以接收到字元編碼,那麼該任務就可以實現字元輸入的功能,各個任務接收到的字元編碼都儲存在其fifo中,在《
30天自製作業系統》中,作者將
fifo
與task
繫結,結構體
fifo
中還有個
task
的指標成員,作者的**執行起來沒有問題,但是我根據作者的步驟編寫出來的作業系統就執行不起來,在
vmware
上就會出現導致虛擬
cpu關閉的錯誤。
所以我直接將命令列任務的fifo在
bookpack.c
定義為全域性變數來避免此問題。
(4)符號的輸入
鍵盤上的有些按鍵與shift鍵結合就可以產生其他字元,為了使得編寫的作業系統可以顯示這些字元,我們需要監測
shift
鍵的狀態,
shift
鍵的按下與抬起都有相應的編碼,只需要監測是否有這些編碼產生即可。 按下
抬起左shift
0x2a
0xaa
右shift
0x36
0xb6
不同字元的編碼不同,為了實現乙個按鍵可以產生兩個字元,我們需要兩套keytable與之對應,大概是因為日本的鍵盤與中國鍵盤有所不同,作者的
keytable
並不能與我的鍵盤完全對應,所以我對
keytable
做了些許修改,修改之後的
keytable
如下:static char keytable0[0x80]=;
static char keytable1[0x80]=', 0, 0,'a','s',
'd','f','g','h','j','k','l',':',0x22, 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 };
(5)大小寫字母轉換
為了盡可能保證鍵盤輸入的正確性,字母的大小寫轉換也是非常必要的。在我們使用電腦的過程中,控制大小寫的就只有兩個鍵:shift鍵和
capslock
鍵。我們可以根據
shift
鍵以及capslock
鍵的狀態來區分輸入的是大寫字母還是小寫字母。
capslock狀態
shift狀態
大寫/小寫
off
off 小寫
off on
大寫 on
off 大寫
on on
小寫
shift鍵狀態的監測只需要根據其按鍵編碼來監測即可,
capslock
鍵的狀態也可以根據其按鍵編碼來監測,但是因為
bios
中儲存有
capslock
鍵的狀態,所以我們採用的方式是通過
binfo
中的leds
來查詢其狀態。
至於大小寫字母的轉換,因為大寫字母的ascii編碼比小寫字母的
ascii
編碼要小
0x20
,所以是很好轉換的。
(6)控制游標閃爍
目前我們的作業系統有兩個視窗:task_a和
console
。當我們選中task_a任務時,希望只有
task_a
視窗的游標閃爍;當選中
console
任務是,希望只有
console
視窗的游標閃爍。
實現該功能的思路是每個視窗都有個變數cursor_c來記錄其游標的顏色,根據定義其正常的取值範圍為
0~15
,那麼我們可以在對其游標顏色作修改之前,先判斷其
cursor_c
的取值是否在正常範圍內,若在正常範圍內,則對其作修改,若不在,則不對其作修改。也就是說當某個視窗的
cursor_c
取值異常時,那麼該視窗的游標就不再閃爍。
之前我們使用tab鍵實現任務的切換,在
harimain
中使用tab
鍵進行任務切換時順便可以對
task_a
的cursor_c
賦值,當任務要切換到
task_a
時,對cursor_c
正常賦值,當任務要切換到
console
是,給cursor_c
賦個非正常值,這樣就實現了
task_a
的游標閃爍的控制。
同時為了控制命令列任務中的游標閃爍,還需要通過命令列的fifo來給命令列傳送游標的控制資訊,在實現過程中定義
2表示命令行視窗游標on,
3表示命令行視窗游標
off。
(7)對回車鍵的支援
命令列任務對回車鍵的支援僅僅通過監聽回車鍵的按鍵編碼即可,監聽到回車鍵之後,游標閃爍位置變為下一行的起始位置,當然下一行要首先顯示提示符。
(8)對視窗滾動的支援
命令列對視窗滾動的支援,實際上就是將命令列視窗中的畫素全都上移一行,最後一行全部塗黑即可。
(9)對相關命令的支援
用命令列執行相關指令一般都是在按下回車鍵之後,在這之前對於任何字元輸入我們都需要將其儲存在cmdline字元陣列中,當按下回車鍵之後,判斷
cmdline
中儲存的內容是啥,然後再作出相關處理。
(10)
dir命令 :顯示檔名等資訊
顯示檔名等資訊需要讀取磁碟,但是當前系統處於32位模式,無法使用
bios
,但是在前面的實現過程中,我們已經讀取了很多內容到記憶體
0x00100000~0x00267fff
(1440kb
)中去。又因為一般像乙個空軟盤儲存檔案時,檔名會寫在
0x002600
以後的地方,檔案的內容會寫在
0x004200
以後的地方,所以我們可以從位址
0x00100000+0x002600
開始的地方開始查詢相關檔案資訊。根據
根據作者實驗可得,每個檔案資訊使用32個位元組來儲存,所以檔案資訊最多存放
(0x004200-0x002600)/32=244
個。檔案資訊的結構如下:
struct fileinfo ;
說明:檔名第乙個位元組為0x00,代表這一段不包含任何檔名資訊;
檔名第乙個位元組為0xe5,代表這一段這個檔案已經刪除。
type值的說明:
0x01 -----
唯讀檔案(不可寫入)
0x02 -----隱藏檔案
0x04 -----系統檔案(比如磁碟名稱等)
0x10 -----目錄
30天自製作業系統
第一天的內容很少,是一些簡單的基礎知識,在這裡我就沒有必要寫出來了,只說出大概的輪廓了,然後我會對其中的幾點進行詳細的解釋。文章的第一天的輪廓大概是這樣的,作者首先用二進位制編輯器做了乙個顯示二進位制的程式,然後用彙編完全db的形式,後又進行改善,最後以比較標準的組合語言編寫,但程式主體部分還沒有翻...
30天自製作業系統 導讀
說明 這是8月15日即將上市的一本新書,本文的摘選也可以命名為 30天自製作業系統 上市之前必讀。本書幽默,有趣,可以說是技術書裡的幽默書,讓您讀起來絕對不會感到乏味。在本書上市之前,您一定先要讀下此篇文章,可以避免在學習中走更多的閱讀彎路,因為更多的讀者會問,七百多頁,30天?是的,看完此篇內容,...
30天自製作業系統 startHaribote
haribote os tab 4 org 0x8400 mov si,msg call putloop mov al,0x13 mov ah,0x00 int 0x10 fin hltjmp fin msg db 0x0a db test db 0 putloop mov al,si add si...