吴进的TC256源程序256basic.h阅读笔记(2)
<P><BR>注释是我加上去的,不知道不明确的正确与否,请指正。<BR><BR>/***********************************************************************************************<BR>// 单扫描线内容拷贝函数,desc与src均使用相对偏移,mode值意义如下:<BR>// 值 意义<BR>// -----------------------------<BR>// 1 EMS屏幕 ---> VRAM屏幕<BR>// -1 VRAM屏幕 ---> 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; // 局部变量:源拷贝起始地址 </P><P> unsigned int descpage=desc>>16, // 目标转换得到BIOS Video(VRAM)页<BR> descoffset=desc&0xffff,// 目标相对VRAM页的偏移<BR> srcpage=src>>16, // 源转换得到BIOS Video(VRAM)页<BR> srcoffset=src&0xffff; // 源相对VRAM页的偏移</P>
<P> if (mode == 1) // EMS ---> VRAM 拷贝<BR> {<BR> descPoint=VPoint; // 目标基地址 = 0xa000<BR> srcPoint=EmsPoint; // 源基地址 = EMS映射内存基地址<BR> pagetype1=1;<BR> pagetype2=0;<BR> }<BR> else // VRAM ---> EMS 拷贝 <BR> {<BR> descPoint=EmsPoint; // 目标基地址 = EMS映射内存基地址<BR> srcPoint=VPoint; // 源基地址 = 0xa000<BR> pagetype1=0;<BR> pagetype2=1;<BR> }<BR>/*----------------------------------------------------------------------------------------------------------------<BR>// 如果 EMS ---> VRAM 拷贝:目标BIOS Video换页, 源EMS逻辑页换页 <BR>// 如果 VRAM ---> EMS 拷贝:目标EMS逻辑页换页, 源BIOS Video换页 <BR>------------------------------------------------------------------------------------------------------------------*/<BR> MySelectpage1(descpage,pagetype1);<BR> MySelectpage1(srcpage,pagetype2);<BR>/*----------------------------------------------------------------------------------------------------------------<BR>// 如果源复制区域及目标复制区域都未超过BIOS Video(VRAM)当前页(1页=65535)<BR>------------------------------------------------------------------------------------------------------------------*/<BR> if ((long)srcoffset+length<=65536L && (long)descoffset+length<=65536L)<BR> {<BR> memcpy(descPoint+descoffset,srcPoint+srcoffset,length);<BR> return;<BR> }<BR>/*----------------------------------------------------------------------------------------------<BR>// 跨页处理(源复制区域或目标复制区域超过BIOS Video(VRAM)当前页,需作跨页处理)<BR>-----------------------------------------------------------------------------------------------*/<BR> else<BR> {<BR> unsigned int passed_length;<BR> if (descoffset == srcoffset) // 传输块与源的offset相同的情况<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 // 传输块与源的offset不同的情况<BR> {<BR> while (length>0)<BR> {<BR> if ((long)srcoffset+length<=65536L && (long)descoffset+length<=65536L)<BR> {<BR> memcpy(descPoint+descoffset,srcPoint+srcoffset,length);<BR> break;<BR> }<BR>/*----------------------------------------------------------------------------------------------<BR>// 目标offset剩余的比源offset多,即源指针比目标指针先到达VRAM页(1页=65535)的尾部<BR>-----------------------------------------------------------------------------------------------*/<BR> if (srcoffset>descoffset)// 说明目标offset剩余的比源offset多<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>// 由于拷贝passed_length长度后,源指针已经到达VRAM页尾部,因此必须将源指针重新修正为0,并换到下页,而目标指针还未到达VRAM尾部,因此,只需修正目标指针即可。<BR> }<BR>/*----------------------------------------------------------------------------------------------<BR>// 源offset剩余的比目标offset多,即目标指针比源指针到达VRAM页(1页=65535)的尾部<BR>-----------------------------------------------------------------------------------------------*/<BR> else // 说明源offset剩余的比目标offset多<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>// 由于拷贝passed_length长度后,目标指针已经到达VRAM页尾部,因此必须将目标指针重新修正为0,并换到下页,而源指针还未到达VRAM尾部,因此,只需修正源指针即可。<BR> }<BR> length-=passed_length; // 剩余待Copy长度<BR> }<BR> }<BR> }<BR>}</P>
<P><BR>/***********************************************************************************************<BR>// 常规内存与EMS或VRAM间的拷贝函数,不带屏幕剪切。<BR>// 入口参数:<BR>// (1).mempos为常规内存指针 (2).destoffset为EMS或VRAM起始点偏移.<BR>// (3).length为待复制长度 (4).mode为数据移动方向<BR>// -----------------------------------------------------------<BR>// 0 常规内存->EMS屏幕 例如:MemCopy256(BmpStackPos,buffer,length,0);<BR>// 将常规内存数组buffer数据移至EMS<BR>// 1 常规内存->VRAM屏幕<BR>// 2 EMS屏幕->常规内存 例如:MemCopy256(HZK_DATA+position,mat,th*2,2); <BR>// 将汉字库汉字字模从EMS拷贝到常规内存数组mat中。<BR>// 3 VRAM屏幕->常规内存<BR>// memcpy函数格式:memcpy(void *dest , void *src , int length)<BR>***********************************************************************************************/<BR>void MemCopy256(unsigned long descoffset,char *mempos,unsigned int length,char mode)<BR>{<BR> unsigned int page=descoffset>>16, // 目标转换成BIOS Video页号<BR> offset=descoffset&0xffff, // 目标相对VRAM页的偏移<BR> part1; // 局部变量<BR> char far* descPoint; // 局部变量:目标拷贝起始地址</P>
<P> if (mode%2) // mode = 1,3 常规内存 <---> VRAM屏幕<BR> descPoint=VPoint; // 目标基地址 = 0xa000<BR> else // mode = 0,2 常规内存 <---> EMS屏幕 <BR> descPoint=EmsPoint; // 目标基地址 = EMS映射基地址<BR> MySelectpage1(page,mode%2); // 目标BIOS Video换页或者目标EMS换页<BR>/*----------------------------------------------------------------------------------------------------------------<BR>// 如果复制区域未超出BIOS Video当前页(1页=65535)<BR>------------------------------------------------------------------------------------------------------------------*/<BR> if ((long)offset+length<=65536L)<BR> {<BR> if (mode/2) // mode = 2,3 EMS屏幕->常规内存或VRAM屏幕->常规内存<BR> memcpy(mempos,descPoint+offset,length);<BR> else // mode = 0,1 常规内存->EMS屏幕或常规内存->VRAM屏幕<BR> memcpy(descPoint+offset,mempos,length);<BR> return;<BR> }<BR>/*----------------------------------------------------------------------------------------------<BR>// 跨页处理 <BR>-----------------------------------------------------------------------------------------------*/<BR> else<BR> {<BR> part1 = 65536L-offset; // 当前页需Copy内容<BR> if (mode/2)<BR> memcpy(mempos,descPoint+offset,part1);<BR> else<BR> memcpy(descPoint+offset,mempos,part1);<BR> MySelectpage1(page+1,mode%2); // 目标BIOS Video或者目标EMS换至下页<BR> length-=part1; // 跨页剩余待Copy内容<BR> if (mode/2)<BR> memcpy(mempos+part1,descPoint,length);<BR> else<BR> memcpy(descPoint,mempos+part1,length);<BR> }<BR>}</P>
<P><BR>/***********************************************************************************************<BR>// 常规内存与绘图屏幕间的水平线拷贝函数,带屏幕剪切。<BR>// (1).mempos为常规内存指针<BR>// (2).(x,y)为屏幕上水平数据线的左起始点<BR>// (3).length为<BR>// (4).mode为数据移动方向<BR>// ------------------------<BR>// 0 常规内存->EMS屏幕<BR>// 1 常规内存->VRAM屏幕<BR>// 2 EMS屏幕->常规内存<BR>// 3 VRAM屏幕->常规内存<BR>***********************************************************************************************/<BR>void screenline_copy(int x,int y,char *mempos,unsigned int length,char mode)<BR>{<BR> unsigned int scan_seek=0,scan_length;<BR> unsigned long descoffset;<BR> <BR> if (x+length<screen_cut.left||x>screen_cut.right||y<screen_cut.top||y>screen_cut.bottom)<BR> return;<BR>/*---------------------------------------------------------------------------------------------<BR>// screen_cut.left ================================== screen_cut.right<BR>// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [copy line]<BR>// x x+length<BR>-----------------------------------------------------------------------------------------------*/<BR> if (x<screen_cut.left) // 如果线的首端超出裁减窗口的左端<BR> scan_seek=screen_cut.left-x;<BR> if (x+length>screen_cut.right) // 如果线的尾端超出裁减窗口右端<BR> scan_length=screen_cut.right-(scan_seek+x)+1;<BR> else // 线的尾端未超出裁减窗口的右端<BR> scan_length=length-scan_seek;<BR> //descoffset=y*640l+x+scan_seek;// 为了提高运算速度,将乘法运算改为移位运算<BR> descoffset=(((unsigned long)y<<9L)+((unsigned long)y<<7L)+((unsigned long)x))+scan_seek;<BR> MemCopy256(descoffset,mempos+scan_seek,scan_length,mode);<BR>}</P>
页:
[1]
