30天自制操作系统第8天

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

操作系统实验日志学号20160810520姓名甘昆禄专业年级班级智能1601实验日期2018.11.14实验项目第8天:鼠标控制与32位模式切换一、实验主要内容1.鼠标解读(1)已经能从鼠标取得数据了,紧接着的问题是要解读这些数据,调查鼠标是怎么移动的,然后结合鼠标的动作,让鼠标指针相应地动起来。首先对bootpack.c中的HariMain进行一些修改:for(;;){io_cli();if(fifo8_status(&keyfifo)+fifo8_status(&mousefifo)==0){io_stihlt();}else{if(fifo8_status(&keyfifo)!=0){i=fifo8_get(&keyfifo);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);}elseif(fifo8_status(&mousefifo)!=0){i=fifo8_get(&mousefifo);io_sti();if(mouse_phase==0)/*等待鼠标的0xfa的状态*/{if(i==0xfa){mouse_phase=1;}}elseif(mouse_phase==1){/*等待鼠标的第一字节*/mouse_dbuf[0]=i;mouse_phase=2;}elseif(mouse_phase==2){/*等待鼠标的第二字节*/mouse_dbuf[1]=i;mouse_phase=3;}elseif(mouse_phase==3){mouse_dbuf[2]=i;mouse_phase=1;/*鼠标的三个字节都齐了,显示出来*/sprintf(s,%02X%02X%02X,mouse_dbuf[0],mouse_dbuf[1],mouse_dbuf[2]);boxfill8(binfo-vram,binfo-scrnx,COL8_008484,32,16,32+8*8-1,31);putfonts8_asc(binfo-vram,binfo-scrnx,32,16,COL8_FFFFFF,s);}}}}实际上是将HariMain中for循环部分进行修改,首先把最初读到的0xfa舍弃掉。之后,每次从鼠标那里送过来的数据都应该是3个字节一组的,所以每当数据累积到3个字节,就把他显示在屏幕上。变量mouse_phase用来记住接受鼠标数据的工作进展到了什么阶段(phase)。接受到的数据放在mouse_dbuf[0~2]内。if(mouse_phase==0)/*等待鼠标的0xfa的状态*/{各种处理;}elseif(mouse_phase==1){/*等待鼠标的第一字节*/各种处理;}elseif(mouse_phase==2){/*等待鼠标的第二字节*/各种处理;}elseif(mouse_phase==3){/*鼠标的三个字节都齐了,显示出来*/各种处理;}这部分就是对于不同的mouse_phase值,相应地做各种不同的处理。显示结果如下(鼠标移动过):屏幕上除了括号内的还有三字节数字,即mouse_dbuf[0],mouse_dbuf[1],mouse_dbuf[2]里的数据。“08”部分0会在0~3的范围内变化,这里鼠标左移时显示1,下移时显示2,这是演讲的同学提出的,湛林莉她观察还真是厉害,不仅将上下左右,还把右下、坐下等也看了出来。“8”只有在点击鼠标时才会有变化,值在8~F之间。第二个字节与鼠标的左右移动有关,第三个字节与鼠标的上下移动有关。这里的信息方便下面为鼠标的动作做出判断。2.整理在HariMain函数中出现的unsignedcharmouse_dbuf[3],mouse_phase;声明可以放到函数前的结构体里:structMOUSE_DEC{unsignedcharbuf[3],phase;};123并在这句话修改为:structMOUSE_DECmdec;1创建的这个结构体MOUSE_DEC,DEC是decode的缩写,用这个结构日把鼠标所需要的变量都归总到一块儿。然后将鼠标的解读从函数HariMain的接受信息处理中剥离出来,放到了mouse_decode函数。3.鼠标解读(2)structMOUSE_DEC{unsignedcharbuf[3],phase;intx,y,btn;};intmouse_decode(structMOUSE_DEC*mdec,unsignedchardat){if(mdec-phase==0){/*等待鼠标的0xfa的阶段*/if(dat==0xfa){mdec-phase=1;}return0;}if(mdec-phase==1){/*等待鼠标第一字节的阶段*/if((dat&0xc8)==0x08){/*如果第一字节正确*/mdec-buf[0]=dat;mdec-phase=2;}return0;}if(mdec-phase==2){/*等待鼠标第二字节的阶段*/mdec-buf[1]=dat;mdec-phase=3;return0;}if(mdec-phase==3){/*等待鼠标第三字节的阶段*/mdec-buf[2]=dat;mdec-phase=1;mdec-btn=mdec-buf[0]&0x07;mdec-x=mdec-buf[1];mdec-y=mdec-buf[2];if((mdec-buf[0]&0x10)!=0){mdec-x|=0xffffff00;}if((mdec-buf[0]&0x20)!=0){mdec-y|=0xffffff00;}mdec-y=-mdec-y;/*鼠标的y方向与画面符号相反*/return1;}return-1;/*应该不可能到这里来*/}结构体里增加的几个变量用于存放解读结果,这几个变量是x、y和btn,分别用于存放移动信息和鼠标按键状态。if(mdec-phase==1)这个语句用于判断第一字节对移动有反应的部分是否在0~3的范围内;同时还要判断第一字节对点击有反应的部分是否在8~F的范围内,如果不在以上数据范围内就被舍去。这样做是因为鼠标连线可能会由接触不良,这样产生的数据就有错位,不能顺利解读。if(mdec-phase==3)语句是解读处理的核心。鼠标键的状态放在buf[0]的低3位,我们只取出这3位。十六进制的0x07相当于二进制的00000111,通过与运算(&)取出低3位。x,y基本上直接使用buf[1]和buf[2],但是需要使用第一字节中对鼠标移动有反应的几位,将x和y的第8位及第8位以后全部都设成1,或全部都保留为0,就能正确解读x和y。解读最后对y符号进行了取反操作是因为鼠标与屏幕的y方向正好相反,为了配合画面方向,就对y符号进行了取反操作。鼠标数据解读完成之后接下来修改显示部分:elseif(fifo8_status(&mousefifo)!=0){i=fifo8_get(&mousefifo);io_sti();if(mouse_decode(&mdec,i)!=0)/*3字节都凑齐了,所以把它们显示出来*/{sprintf(s,[lcr%4d%4d],mdec.x,mdec.y);if((mdec.btn&0x01)!=0){s[1]='L';}if((mdec.btn&0x02)!=0){s[3]='R';}if((mdec.btn&0x04)!=0){s[2]='C';}boxfill8(binfo-vram,binfo-scrnx,COL8_008484,32,16,32+15*8-1,31);putfonts8_asc(binfo-vram,binfo-scrnx,32,16,COL8_FFFFFF,s);}}4.移动鼠标指针现在就是让鼠标指针在屏幕上动起来啦,感觉好激动,终于能动了(白眼)。elseif(fifo8_status(&mousefifo)!=0){i=fifo8_get(&mousefifo);io_sti();if(mouse_decode(&mdec,i)!=0)/*3字节都凑齐了,所以把它们显示出来*/{sprintf(s,[lcr%4d%4d],mdec.x,mdec.y);if((mdec.btn&0x01)!=0){s[1]='L';}if((mdec.btn&0x02)!=0){s[3]='R';}if((mdec.btn&0x04)!=0){s[2]='C';}boxfill8(binfo-vram,binfo-scrnx,COL8_008484,32,16,32+15*8-1,31);putfonts8_asc(binfo-vram,binfo-scrnx,32,16,COL8_FFFFFF,s);/*鼠标指针的移动*/boxfill8(binfo-vram,binfo-scrnx,COL8_008484,mx,my,mx+15*8-1,my+15);/*隐藏鼠标*/mx+=mdec.x;my+=mdec.y;if(mxx){mx=0;}if(my0){my=0;}if(mxbinfo-scrnx-16){mx=binfo-scrnx-16;}if(mybinfo-scrny-16){my=binfo-scrny-16;}sprintf(s,(%sd,%3d),mx,my);boxfill8(binfo-vram,binfo-scrnx,COL8_008484,0,0,79,15);/*隐藏坐标*/putfonts8_asc(binfo-vram,binfo-scrnx,0,0,COL8_FFFFFF,s);/*显示坐标*/putfonts8_8(binfo-vram,binfo-scrnx,16,16,mx,my,mcursor,16);/*描画鼠标*/}先隐藏到鼠标指针,然后根据取得的鼠标数据解读得到的位移量,让鼠标显示在屏幕上。mx+=mdec.x;my+=mdec.y;是为了防止鼠标指针跑到屏幕外进行的调整。5.通往32位模式之路这里讲解了asmhead.nas中的程序。;PIC关闭一切中断;根据AT兼容机的规格,如果要初始化PIC,;必须在CLI之前进行,否则有时会挂起,;随后进行PIC的初始化MOVAL,0xffOUT0x21,ALNOP;如果连续执行OUT指令,有些机种会无法正常运行OUT0xa1,ALCLI;禁止CPU级别的中断这段程序等同于一下内容的C程序。io_out8(PIC0_IMR,0xff);/*禁止主PIC的全部中断*/io_out8(PIC1_IMR,0xff);/*禁止从PIC的全部中断*/Io_cli();/*禁止CPU级别的中断*/为了让CPU能够访问1MB以上的内存空间,设定A20GATECALLwaitkbdoutMOVAL,0xd1OUT0x64,ALCALLwaitkbdoutMOVAL,0xdf;enableA20OUT0x60,ALCALLwaitkbdout1234567这里的waitbdout等同于wait_KBC_sendread,等同于C语言中的:#defineKEYCMD_WRITE_OUTPORT0xd1#defineKBC_OUTPORT_A20G_ENABLE0xdf/*A20GATE的设定*/Wait_KBC_sendready();Io_out8(PORT_KEYCMD,KEYCMD_WRITE_OUTPORT);Waite_KBC_sendready();Io_out8(PORT_KEYDATA,KBC_OUTPORT_A20G_ENABLE);Waite_KBC_sendready();/*这句

1 / 26
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功