编程论坛's Archiver

ba_wang_mao 发表于 2006-12-28 13:44

吴进的256basic.h阅读笔记,请问scanline_copy子程序为什么要分三种情况考虑:(1)d

<P>注释是我加上去的,不知我的理解是否正确,望给予赐教。<BR><BR>/***********************************************************************************************<BR>//    BIOS Video 换页或者 EMS换页函数<BR>***********************************************************************************************/<BR>void MySelectpage1(unsigned int page,char mode)<BR>{<BR>    if (mode)                            // BIOS Video换页<BR>    {<BR>        if (lastVpage!=page)<BR>            selectpage(page);            // 调用BIOS Video 换页函数<BR>    }<BR>    else                                // EMS换页<BR>    {<BR>        char n;<BR>        for (n = 0 ; n &lt; 4 ; n++)<BR>        {<BR>            if (page*4+n!=lastEmap[n])<BR>                emap(page*4+n,n);        // EMS逻辑页page*4+n与物理页n(n=0-4)建立映射<BR>        }<BR>    }<BR>}<BR><BR><BR>/***********************************************************************************************<BR>//  单扫描线内容拷贝函数,desc与src均使用相对偏移,mode值意义如下:<BR>//  值       意义<BR>//  -----------------------------<BR>//   1     EMS屏幕 ---&gt; VRAM屏幕<BR>//  -1    VRAM屏幕 ---&gt; EMS屏幕<BR>***********************************************************************************************/<BR>void scanline_copy(unsigned long desc,unsigned long src,unsigned int length,char mode)<BR>{<BR>    char pagetype1,pagetype2;<BR>    char far* descPoint;<BR>    char far* srcPoint;<BR>    unsigned int descpage=desc&gt;&gt;16,        // 目标转换得到BIOS Video页<BR>                   descoffset=desc&amp;0xffff,// 目标相对VRAM页的偏移<BR>                   srcpage=src&gt;&gt;16,        // 源转换得到BIOS Video页<BR>                   srcoffset=src&amp;0xffff;    // 源相对VRAM页的偏移</P>
<P>    if (mode == 1)                        // EMS ---&gt; VRAM 拷贝<BR>     {<BR>        descPoint=VPoint;                // 目标基地址 = 0xa000<BR>        srcPoint=EmsPoint;                // 源基地址 = EMS映射内存基地址<BR>          pagetype1=1;<BR>        pagetype2=0;<BR>    }<BR>    else                                // VRAM ---&gt; EMS 拷贝    <BR>    {<BR>        descPoint=EmsPoint;                // 目标基地址 = EMS映射内存基地址<BR>        srcPoint=VPoint;                // 源基地址 = 0xa000<BR>          pagetype1=0;<BR>        pagetype2=1;<BR>    }<BR>/*----------------------------------------------------------------------------------------------------------------<BR>// 如果 EMS ---&gt; VRAM 拷贝:目标BIOS Video换页, 源EMS逻辑页换页 <BR>// 如果 VRAM ---&gt; EMS 拷贝:目标EMS逻辑页换页, 源BIOS Video换页 <BR>------------------------------------------------------------------------------------------------------------------*/<BR>    MySelectpage1(descpage,pagetype1);<BR>     MySelectpage1(srcpage,pagetype2);<BR>/*----------------------------------------------------------------------------------------------------------------<BR>// 如果源复制区域及目标复制区域都未超过BIOS Video当前页(1页=65535Byte)<BR>------------------------------------------------------------------------------------------------------------------*/<BR>     if ((long)srcoffset+length&lt;=65536L &amp;&amp; (long)descoffset+length&lt;=65536L)<BR>    {<BR>        memcpy(descPoint+descoffset,srcPoint+srcoffset,length);<BR>          return;<BR>     }<BR>/*----------------------------------------------------------------------------------------------<BR>// 跨页处理(源复制区域或目标复制区域超过BIOS Video当前页,需作跨页处理)<BR>-----------------------------------------------------------------------------------------------*/<BR>     else<BR>     {<BR>        unsigned int passed_length;<BR>          if (descoffset == srcoffset)    // 如果目标位置与源位置相同<BR>          {<BR>            passed_length=65536L-descoffset;//当前页可Copy字节<BR>               memcpy(descPoint+descoffset,srcPoint+srcoffset,passed_length);<BR>               MySelectpage1(descpage+1,pagetype1);    // 目标换至下页<BR>            MySelectpage1(srcpage+1,pagetype2);        // 源换至下页<BR>               memcpy(descPoint,srcPoint,length-passed_length);// 复制跨页剩余内容<BR>          }<BR>          else                            // 目标与源位置不同<BR>          {<BR>            while (length&gt;0)<BR>               {<BR>                if ((long)srcoffset+length&lt;=65536L &amp;&amp; (long)descoffset+length&lt;=65536L)<BR>                {<BR>                    memcpy(descPoint+descoffset,srcPoint+srcoffset,length);<BR>                    break;<BR>                }<BR>                   if (srcoffset&gt;descoffset)// 如果源偏移位置大于目标偏移位置<BR>                {<BR>                    passed_length=65536L-srcoffset;// 当前页Copy长度<BR>                     memcpy(descPoint+descoffset,srcPoint+srcoffset,passed_length);<BR>                     srcpage++;            // 源页号+1<BR>                    MySelectpage1(srcpage,pagetype2);// 源换至下页<BR>                     descoffset+=passed_length;// 修正目标偏移<BR>                     srcoffset=0;        // 修正源偏移:由于源已经换页,因此偏移从0重新开始。<BR>                }<BR>                else                    // 源位置小于目标位置<BR>                {<BR>                    passed_length=65536L-descoffset;// 当前页Copy长度<BR>                     memcpy(descPoint+descoffset,srcPoint+srcoffset,passed_length);<BR>                     descpage++;            // 目标页号+1<BR>                     MySelectpage1(descpage,pagetype1);// 目标换至下页<BR>                     srcoffset+=passed_length;// 修正源偏移<BR>                    descoffset=0;        // 修正目标偏移:由于目标已经换页,因此偏移从0重新开始。<BR>                }<BR>                length-=passed_length;    // 剩余待Copy长度<BR>               }<BR>          }<BR>      }<BR>}<BR></P>

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.