• Thứ Hai, 22/12/2003 10:42 (GMT+7)

    Câu hỏi :
    Pascal có hàm nào xóa bộ đệm của bàn phím không? Nếu có thì xin cho 1 đoạn mã ví dụ, nếu không có thì xin hướng dẫn cách giải quyết.

    Trả lời :
     

    Không có hàm nào trong thư viện run-time của Pascal thực hiện xóa bộ đệm của bàn phím cả. Tuy nhiên nếu bạn biết chính xác cấu trúc và vị trí của bộ đệm bàn phím trong DOS thì việc xóa bộ đệm rất dễ dàng. Thực vậy, DOS dùng 16 word (32 byte) từ địa chỉ 40h:1eh tới 40h:3dh để chứa thông tin của tối đa 16 phím vừa ấn, mỗi phím dùng 2 byte: 1 byte miêu tả mã ASCII của phím ấn, 1 byte miêu tả mã scancode của phím ấn. Bộ đệm bàn phím được quản lý theo dạng danh sách vòng được xác định bởi 2 đầu: đầu danh sách (buffer_head) miêu tả vị trí nhớ chứa thông tin về phím sắp sửa được ấn, đuôi danh sách (buffer_tail) miêu tả vị trí nhớ chứa thông tin về phím sắp sửa được ứng dụng lấy dùng. Vị trí buffer_head được lưu ở ô nhớ 40h:1ah, vị trí buffer_tail được lưu ở ô nhớ 40h:1ch. Tóm lại việc xóa bộ đệm bàn phím tương ứng với việc hiệu chỉnh buffer_head và buffer_tail về cùng 1 địa chỉ (thí dụ địa chỉ 1eh là đầu vùng nhớ đệm). Để giúp bạn thấy rõ hơn, chúng tôi liệt kê chương trình Pascal nhỏ sau đây, nó có chức năng chờ nhận từng phím ấn và hiển thị lên màn hình ký tự đó rồi bỏ các phím ấn trong 30s sau đó trước khi chờ nhận phím kế tiếp.

    program keytest;

    Uses Dos, Crt;

    var ch : Char;

    { Thủ tục xóa bộ đệm bàn phím được viết bằng assembly }

    Procedure ClearKeyBuf;

    begin

    asm

       cli

       push ds

       mov ax,40h

       mov ds,ax

       mov ax,1eh

       mov bx,1ah

       mov [bx],ax

       mov bx,1ch

       mov [bx],ax

       pop ds

       sti

    end;

    end;

    { Thủ tục ngủ time giây, trong lúc ngủ xóa bộ đệm phím }

    Procedure Sleep (time : Word);

    var sh, sm, ss, sp : Word;

       crh, crm, crs, crp : Word;

    begin

        Gettime (sh,sm,ss,sp);

        repeat

          ClearKeyBuf; {xóa bộ đệm}

          Gettime(crh,crm,crs,crp);

          if crh <> sh then crm := crm+60;

          if crm > sm then crs := crs+60;

        until crs-ss >= time;

    end;

    { Chương trình nhận phím và hiển thị }

    begin

      clrscr;

      repeat

        { Chờ nhận 1 phím }

        ch := ReadKey;

        { Hiển thị ký tự ra màn hình }

        write (ch);

        { ngủ 30s và xóa bộ đệm phím ấn trong 30s này }

        Sleep (30);

      until ch = ‘q’ { đến khi phím q được ấn }

    end.

    Chuyên mục: Lập trình