官术网_书友最值得收藏!

3 制作FIFO緩沖區(harib04c)

問題到底出在哪兒呢?在于筆者所創建的緩沖區,它只能存儲一個字節。如果做一個能夠存儲多字節的緩沖區,那么它就不會馬上存滿,這個問題也就解決了。

最簡單的解決方案是像下面這樣增加變量。

struct KEYBUF {
    unsigned char data1, data2, data3, data4, ...
};

但這樣一來,程序就變長了,所以將它寫成下面這樣:

struct KEYBUF {
    unsigned char data[4];
};

當我們使用這些緩沖區的時候,可以寫成data[0]、data[1]等。至于創建得是否正常,那就是后話了。

說起緩沖,我們在講棧的時候,曾講過FIFO、FILO等,這次我們需要的是FIFO型。為什么呢?如果輸入的是ABC,輸出的時候,卻把順序搞反了,寫成CBA,那可就麻煩了。所以需要按照輸入數據的順序輸出數據。

根據這種思路,我們制作了以下程序:

int.c節選

struct KEYBUF {
    unsigned char data[32];
    int next;
};

void inthandler21(int *esp)
{
    unsigned char data;
    io_out8(PIC0_OCW2, 0x61);   /* 通知PIC IRQ-01已經受理完畢 */
    data = io_in8(PORT_KEYDAT);
    if (keybuf.next < 32) {
        keybuf.data[keybuf.next] = data;
        keybuf.next++;
    }
    return;
}

keybuf.next的起始點是“0”,所以最初存儲的數據是keybuf.data[0]。下一個數據是keybuf.data[1],接著是[2],依此類推,一共有32個存儲位置。

下一個存儲位置用變量next來管理。next,就是“下一個”的意思。這樣就可以記住32個數據,而不會溢出。但是為了保險起見,next的值變成32之后,就舍去不要了。

■■■■■

取得數據的程序如下所示。

for (; ; ) {
    io_cli();
    if (keybuf.next == 0) {
        io_stihlt();
    } else {
        i = keybuf.data[0];
        keybuf.next——;
        for (j = 0; j < keybuf.next; j++) {
            keybuf.data[j] = keybuf.data[j + 1];
        }
        io_sti();
        sprintf(s, "%02X", i);
        boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31);
        putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);
    }
}

如果next不是0,則說明至少有一個數據。最開始的一個數據肯定是放在data[0]中的,將這個數存入到變量i中去。這樣,數就減少了一個,所以將next減去1。

接下來的for語句,我們用下圖來說明它所完成的工作。

像上面這樣,數據的存放位置全部都向前移送了一個位置。如果不移送的話,下一次就不能從data[0]讀入數據了。

■■■■■

那好,我們趕緊測試一下,看看能不能正常運行?!癿ake run”,按下右Ctrl鍵,哦,運行正常!

雖然現在想說這個程序已經OK了,但實際上還是有問題。還有些地方還不盡如人意。inthandler21可以了,完全沒有問題。有問題的是HariMain。說得具體一點,是從data[0]取得數據后有關數據移送的處理不能讓人滿意。

像這種移送數據的處理,一般說來也就不超過3個,基本上沒有什么問題。但運氣不好的時候,我們可能需要移送多達32個數據。雖然這遠比顯示字符所需的128個像素要少,但要是有辦法避免這種操作的話,當然是最好不過了。

數據移送處理本身并沒有什么不好,只是在禁止中斷的期間里做數據移送處理有問題。但如果在數據移送處理前就允許中斷的話,會搞亂要處理的數據,這當然不行。那該怎么辦才好呢?接下來的harib04d章節就要講述這個問題了。

主站蜘蛛池模板: 沙雅县| 屯门区| 曲水县| 博乐市| 蓝山县| 长阳| 余庆县| 汽车| 南京市| 白河县| 达拉特旗| 正宁县| 吴桥县| 浦县| 泸溪县| 白银市| 乐都县| 富源县| 自治县| 许昌县| 德保县| 门源| 乐清市| 兴城市| 祥云县| 宁陵县| 龙游县| 赫章县| 册亨县| 山东省| 花莲县| 佛山市| 苏尼特左旗| 石台县| 阿拉善盟| 于都县| 叶城县| 安阳县| 扎囊县| 水城县| 邮箱|