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