操作系统学习初步-解读鼠标

操作系统学习初步-解读鼠标

在这里插入图片描述

  -- 以下是控制器的一些定义
  --  programmable Interrupt Controller port
  PIC0_ICW1	:constant:=16#0020#;
  PIC0_OCW2	:constant:=16#0020#;
  PIC0_IMR	    :constant:=16#0021#;
  PIC0_ICW2	:constant:=16#0021#;
  PIC0_ICW3	:constant:=16#0021#;
  PIC0_ICW4	:constant:=16#0021#;
  PIC1_ICW1	:constant:=16#00a0#;
  PIC1_OCW2	:constant:=16#00a0#;
  PIC1_IMR	    :constant:=16#00a1#;
  PIC1_ICW2	:constant:=16#00a1#;
  PIC1_ICW3	:constant:=16#00a1#;
  PIC1_ICW4	:constant:=16#00a1#;
  
  -- 8259A chip interrupt request
  -- chip master
  irq_clock1  :constant:=0;
  irq_keyboard:constant:=1;
  irq_link    :constant:=2;
  irq_ata2    :constant:=3;
  irq_ata1    :constant:=4;
  irq_ide2    :constant:=5;
  irq_floppy  :constant:=6;
  irq_ide1    :constant:=7;
  
  -- chip slave
  irq_clock2    :constant:=8;
  irq_mouse    :constant:=12;
  irq_harddisk  :constant:=14;
  irq_hd       :constant:=14;
 
-- 以下是8259可编程控制器的初始化代码:
procedure init_pic is
begin
    asm("cli",volatile=>true);
    outb(PIC0_IMR,16#ff#);
    outb(PIC1_IMR,16#ff#);
    outb(PIC0_ICW1,16#11#);
    outb(PIC0_ICW2,16#20#);
  	outb(PIC0_ICW3,4);
  	outb(PIC0_ICW4,01);
    outb(PIC1_ICW1,16#11#);
    outb(PIC1_ICW2,16#28#);
    outb(PIC1_ICW3,2);
    outb(PIC1_ICW4,1);
    outb(PIC0_IMR,16#ff#);
    outb(PIC1_IMR,16#ff#);
    asm("sti",volatile=>true);
end init_pic;
 
--  以下是开启8237通道的代码(如果是从片的则打开主片的第2号通道):
procedure enable_irq(irq_no:dword) is
    mask:byte;
begin
    if irq_no<8 then
      mask:=inb(16#21#) and (16#ff# xor (shift_left(1,natural(irq_no))));
      outb(16#21#,dword(mask));
    elsif irq_no>7 and irq_no<16 then
      mask:=inb(16#21#) and (16#ff# xor (shift_left(1,natural(irq_link))));
      outb(16#21#,dword(mask));
      mask:=inb(16#a1#) and (16#ff# xor (shift_left(1,natural(irq_no-8))));
      outb(16#a1#,dword(mask));
    end if;
end enable_irq;
 
-- 以下是开启鼠标控制电路:
 
procedure wait_kbdController_ready is
begin
    loop
      exit when (inb(16#64#) and 2)=0; 
    end loop;
end wait_kbdController_ready;
  
  
  procedure enable_mouse is
  begin
    wait_kbdController_ready;
    outb(16#64#,16#60#);
    wait_kbdController_ready;
    outb(16#60#,16#47#);
    wait_kbdController_ready;
    outb(16#64#,16#d4#);
    wait_kbdController_ready;
    outb(16#60#,16#f4#);
    wait_kbdController_ready;
  end enable_mouse;
 
-- 定义鼠标解码结构:
type MouseDecode is record
    phase :byte;
    button:byte;
    xmove :char;
    ymove :char;
    x     :integer;             -- current screen x
    y     :integer;
 ICON  :byte_array(0..11):=(16#80#,16#c0#,16#e0#,16#f0#,16#f8#,16#fc#,16#fe#,16#ff#,16#f8#,16#f8#,16#cc#,16#8c#);
end record;
for mouseDecode'alignment use 1;
type lpMouseDecode is access all MouseDecode;
 
-- Button为按键状态,xmove,ymove为鼠标移动量信息,请注意是有符号的。X,y记录鼠标原始位置。ICON中定义了12个字节(8个点每字节)的点阵鼠标图标。
 
 
-- 以下do_mouse为鼠标中断函数。
 
procedure draw_mouse(md:lpmousedecode) is
    bt:byte:=2#1000_0000#;
    icon:byte_array(0..11):=(16#80#,16#c0#,16#e0#,16#f0#,16#f8#,16#fc#,16#fe#,16#ff#,16#f8#,16#f8#,16#cc#,16#8c#);
  begin
    icon(0):=16#80#;
    fill_rectangle24(1024,768,dword(md.x),dword(md.y),dword(md.x)+dword(8),dword(md.y)+dword(12),16#48d1cc#);
    for j in 0..11 loop
      for i in 0..7 loop
        if (icon(j) and bt)/=0 then
          draw_pixel24(1024,768,dword(md.x+int(md.xmove)+i),dword(md.y+int(md.ymove)+j),16#00ff0000#);
        end if;
        bt:=shift_right(bt,1);
      end loop;
      bt:=2#10000000#;
    end loop;
    md.x:=(if (md.x+int(md.xmove))<1 then 1 elsif (md.x+int(md.xmove))>1024 then 1024 else md.x+int(md.xmove));
    md.y:=(if (md.y+int(md.ymove))<1 then 1 elsif (md.y+int(md.ymove))>768 then 768 else md.y+int(md.ymove));
  end draw_mouse;
  
  
  procedure do_mouse is
    B1:byte:=0;
    md:lpMouseDecode;
    pragma import(c,md,"keyboards__pmousedec");
  begin
    asm("cli",volatile=>true);
    outb(PIC1_OCW2,16#64#);
    outb(PIC0_OCW2,16#62#);
    B1:=inb(16#60#);
    if b1/=16#fa# then
      md.button:=b1;
      B1:=inb(16#60#);
      md.xmove:=char(B1);
      b1:=inb(16#60#);
      md.ymove:=-char(B1);
      draw_mouse(md);
    end if;
    asm("sti",volatile=>true);
    asm("leave"&nl&"iretl",volatile=>true);
  end do_mouse;

猜你喜欢

转载自blog.csdn.net/adacore/article/details/82861818