-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪-----------------------
.
.
.
.
.
.
.
.
.
-
準備環境
略
-
Demo
鍵盤功能主要由如下幾個部分實作:
keyboard.S:接受鍵盤中斷回報的鍵盤碼。
tty_io.c :二級處理輸入資料
console.c :三級處理,之後列印到控制台
.
大緻流程如下
keyboards(read/put_queue)------>tty_io(write_queue)—>console(asm)---->螢幕
.
按實驗提示找到關鍵檔案keyboards.S console.c tty_io.c,後面要做的修改集中于這三個檔案之中。運作Bochs模拟器,在按下F頭的幾個按鍵之後發現有迫真大量(四行)狀态資訊輸出,影響實驗操作,是以先注釋掉keyboards.S中第214行對show_stat的調用。
在判斷不是F12的語句( cmpb $11, %al ja end_func)後添加call指令,由于沒有參數,是以不需要進行其他操作CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪----------------------- 在console.c中添加如下内容CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪----------------------- 在下方的con_write函數中添加如下内容,隻修改列印到控制台後的狀态CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪----------------------- cd進入linux-0.11目錄,make clean一下,然後重新make,cd …傳回上層,輸入./run運作模拟器,效果如下CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪----------------------- 雖然已經實作基本功能,但是按下F12時會有字元L溢出顯示,修改如下CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪----------------------- CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪----------------------- 即處理F12後立即結束
此外,也可以全在keyborads interrupt中處理F12事件,注冊.global變量後在c中extern引用即可。
.
-
Phase1
實驗要求鍵入F12激活※功能,鍵入學生姓名拼音,首尾字母等顯示※,例如:zhangsan,顯示為: ※ha※gsa※
第二部分的需求的實作比較麻煩,以我的了解來看就是每輸入一個字元進行一次判斷,先記錄坐标和狀态,若為合法的拼音聲母開頭字元則将其記錄并加密,若其中插入了非法字元則判斷中斷,還原顯示,直到最後一個合法的韻母結尾為之,結束這一段的更改,其中更新狀态也應該被倒退鍵這些按鍵觸發…
.
總結一下,先設定一個狀态變量status_phase來對操作狀态進行判斷。當沒有輸入&完成了一串拼音的加密&由于一些非法字元的輸入中斷了加密時,這個值置為0。開始正常接收輸入時,這個值置為1
.
随後,設定兩個變量pos_cache&recent_length來控制對緩沖區内容的讀取。pos_cache記錄最後一次處理開始時的緩沖區内容起始位置,每輸入一個字元操作recent_length進行增減後從記錄的位置開始一次周遊,先删去輸入數量的字元數,再調用__asm__根據緩存重新列印字元到控制台。
.
先來看看tty對各種行為的定義
以上定義了tty 等待隊列中緩沖區操作宏函數,每一個tty結構中會附帶三個tty_queue,發現緩沖區是利用循環隊列實作的,在進行操作時并不會直接修改其中隊列的緩沖區記憶體,我們可以利用這一點直接對緩沖區中的内容進行讀取,然後在console.c中進行修改,調用csi_p和周遊緩沖區資料并輸出到控制台來操作列印出的内容。CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪----------------------- CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪----------------------- 根據我的思路主要用到的函數(删除光标處的p個字元)然後在讀取并列印内容時選擇根據自己設定的偏移量進行讀取
.
其餘可選的還有直接操作x和pos,循環調用del等,這裡放一個我的簡單實作版本,檢測什麼的隻做了簡單的判斷,控制按鍵之類的也沒做處理想做處理的話可以根據字元寬度調整startPos的位置與輸出政策,輸入的内容具體是不是拼音可以寫個樹做狀态機自己體驗一下…本人實屬一條懶狗 ,大半夜寫的邏輯比較亂,總之各位可以運作一下看看笑話,權當抛磚引玉。
.
注:按2下F12激活此模式,下圖為預覽效果:
替換console.c中的con_write及添加部分代碼CSAPP LAB4 鍵盤驅動程式的分析與修改(謝罪)-------------不用往下看力,,我實驗想多了導緻畫蛇添足,請各位大手子根據實驗報告要求編寫,在此謝罪-----------------------
#define START 0
#define HANDLEING 1
#define EXITED 2
static unsigned char f12Flag = 0;
static unsigned char ph1Flag = 0;
static int startedPos = 0; //record current position
static unsigned char status_phase = 0; //record display status
static int puttedCnt = 0; //record the number of input section
static unsigned char inited_phase = 0;
void changed_f12Flag(void) {
f12Flag = ++f12Flag % 2;
ph1Flag++;
if(ph1Flag == 2) {
startedPos = 0;
status_phase = EXITED;
}
}
static void print2console(const char c) {
if(!(c>31 && c<127))
return;
if (x>=video_num_columns) {
x -= video_num_columns;
pos -= video_size_row;
lf();
}
__asm__("movb attr,%%ah\n\t"
"movw %%ax,%1\n\t"
::"a" (c),"m" (*(short *)pos)
);
pos += 2;
x++;
}
static void printCacheBuffer(struct tty_struct* tty) {
//restore_cur();
int k;
for(k = 0; k < puttedCnt - 1; k++) {
x--;
pos -= 2;
set_cursor();
//del();
}
//csi_P(puttedCnt - 1);
int i = startedPos, j;
for(j = 0; j < puttedCnt; j++) {
if(i+j >= TTY_BUF_SIZE)
j = (i+j) % TTY_BUF_SIZE - i;
char temp = tty->secondary.buf[i+j];
if(status_phase == HANDLEING) {
char _begin = tty->secondary.buf[i];
char _end = tty->secondary.buf[i+puttedCnt - 1];
if(temp == _begin || temp == _begin - (_begin/97)*32 ||
temp == _end || temp == _end - (_end/97)*32
)
temp = '*';
}
print2console(temp);
}
//save_cur();
}
static void phase_1_func(const int cnt, struct tty_struct * tty) {
switch(status_phase) {
case START:
puttedCnt = cnt;
break;
case HANDLEING:
puttedCnt += cnt;
break;
case EXITED:
startedPos += puttedCnt;
puttedCnt = cnt;
break;
default:
puttedCnt += cnt;
break;
}
printCacheBuffer(tty);
}
void con_write(struct tty_struct * tty)
{
int nr;
char c;
int pd = 1;
nr = CHARS(tty->write_q);
while (nr--) {
GETCH(tty->write_q,c);
switch(state) {
case 0:
if (c>31 && c<127) {
if((c>64&&c<91) || (c>96&&c<123)) {
if(f12Flag)
c = '*';
if(ph1Flag) {
if(status_phase == START) {
status_phase = HANDLEING;
}
else if(status_phase == EXITED) {
if(inited_phase)
startedPos += 1;
else
inited_phase = 1;
status_phase = START;
}
}
pd = 0;
} else if(status_phase == HANDLEING)
status_phase = EXITED;
if(ph1Flag == 2) {
phase_1_func(1, tty);
} else {
startedPos = (++startedPos) % TTY_BUF_SIZE;
print2console(c);
}
} else if (c==27)
state=1;
else if (c==10 || c==11 || c==12)
lf();
else if (c==13)
cr();
else if (c==ERASE_CHAR(tty))
del();
else if (c==8) {
if (x) {
x--;
pos -= 2;
}
} else if (c==9) {
c=8-(x&7);
x += c;
pos += c<<1;
if (x>video_num_columns) {
x -= video_num_columns;
pos -= video_size_row;
lf();
}
c=9;
} else if (c==7)
sysbeep();
break;
case 1:
state=0;
if (c=='[')
state=2;
else if (c=='E')
gotoxy(0,y+1);
else if (c=='M')
ri();
else if (c=='D')
lf();
else if (c=='Z')
respond(tty);
else if (x=='7')
save_cur();
else if (x=='8')
restore_cur();
break;
case 2:
for(npar=0;npar<NPAR;npar++)
par[npar]=0;
npar=0;
state=3;
if ((ques=(c=='?')))
break;
case 3:
if (c==';' && npar<NPAR-1) {
npar++;
break;
} else if (c>='0' && c<='9') {
par[npar]=10*par[npar]+c-'0';
break;
} else state=4;
case 4:
state=0;
switch(c) {
case 'G': case '`':
if (par[0]) par[0]--;
gotoxy(par[0],y);
break;
case 'A':
if (!par[0]) par[0]++;
gotoxy(x,y-par[0]);
break;
case 'B': case 'e':
if (!par[0]) par[0]++;
gotoxy(x,y+par[0]);
break;
case 'C': case 'a':
if (!par[0]) par[0]++;
gotoxy(x+par[0],y);
break;
case 'D':
if (!par[0]) par[0]++;
gotoxy(x-par[0],y);
break;
case 'E':
if (!par[0]) par[0]++;
gotoxy(0,y+par[0]);
break;
case 'F':
if (!par[0]) par[0]++;
gotoxy(0,y-par[0]);
break;
case 'd':
if (par[0]) par[0]--;
gotoxy(x,par[0]);
break;
case 'H': case 'f':
if (par[0]) par[0]--;
if (par[1]) par[1]--;
gotoxy(par[1],par[0]);
break;
case 'J':
csi_J(par[0]);
break;
case 'K':
csi_K(par[0]);
break;
case 'L':
csi_L(par[0]);
break;
case 'M':
csi_M(par[0]);
break;
case 'P':
csi_P(par[0]);
break;
case '@':
csi_at(par[0]);
break;
case 'm':
csi_m();
break;
case 'r':
if (par[0]) par[0]--;
if (!par[1]) par[1] = video_num_lines;
if (par[0] < par[1] &&
par[1] <= video_num_lines) {
top=par[0];
bottom=par[1];
}
break;
case 's':
save_cur();
break;
case 'u':
restore_cur();
break;
}
}
if(pd)
status_phase = EXITED;
}
set_cursor();
}