ba_wang_mao 发表于 2006-12-30 16:54

吴进的TC256源程序256basic.h阅读笔记(1)

<P>注释是我加上去的,不知道不明确的正确与否,请指正。<BR><BR>/***********************************************************************************************<BR>//    640*480*256写点函数,允许使用点模式。<BR>***********************************************************************************************/<BR>void putpixel(register int x,register int y,register unsigned char color)<BR>{<BR>    register unsigned char n;<BR>    register unsigned char far *descpoint;<BR>    register long temp=(((unsigned long)y&lt;&lt;9L)+((unsigned long)y&lt;&lt;7L)+((unsigned long)x));<BR>    register unsigned int nowVpage,nowEmap;</P>
<P>    if (x&lt;screen_cut.left||x&gt;screen_cut.right||y&lt;screen_cut.top||y&gt;screen_cut.bottom)<BR>        return;<BR>    if(SurfaceMode)                        // 如果缓冲形式为:无缓冲页<BR>    {<BR>        nowVpage = temp&gt;&gt;16;            // 像素点转换成BIOS Video页号(64K为单位)<BR>        if(nowVpage!=lastVpage)<BR>        {<BR>            selectpage(nowVpage);        // BIOS Video 换页<BR>            lastVpage=nowVpage;<BR>        }<BR>        temp&amp;=0xffff;                    // 像素点相对 BIOS Video 页中的偏移<BR>        descpoint=VPoint;                // 基地址 = 0xA000<BR>    }<BR>    else                                // 缓冲形式为:单缓冲页<BR>    {<BR>        nowEmap=temp&gt;&gt;14;                // 像素点转换成EMS 逻辑页号(16K为单位)<BR>        if (nowEmap!=lastEmap[0])        <BR>            emap(nowEmap,0);            // 物理页号0与逻辑页号nowEmap建立射关系<BR>        temp&amp;=0x3fff;                    // 像素点相对EMS逻辑页号中的偏移<BR>        descpoint=EmsPoint;                // 基地址 = EMS基地址<BR>    }<BR>    switch(PIXEL_MODE)                    // (基地址+偏移)位置按照下述方式填充<BR>    {                            <BR>        case COPY_PUT     :*(descpoint+(int)temp)=color;break;//直接传输<BR>        case INVERT_PUT   :*(descpoint+(int)temp)=~*(descpoint+temp);break; //目标取反传输<BR>        case OR_PUT       :*(descpoint+(int)temp)=*(descpoint+temp)|color;break;//或传输<BR>        case AND_PUT      :*(descpoint+(int)temp)=*(descpoint+temp)&amp;color;break;//与传输<BR>        case XOR_PUT      :*(descpoint+(int)temp)=*(descpoint+temp)^color;//异或传输<BR>    }<BR>}</P>
<P><BR>/***********************************************************************************************<BR>//    640*480*256读取像素颜色函数<BR>***********************************************************************************************/<BR>unsigned char getpixel(register int x,register int y) <BR>{<BR>    register long temp=(((unsigned long)y&lt;&lt;9L)+((unsigned long)y&lt;&lt;7L)+((unsigned long)x));<BR>    register int nowEmap,n;<BR> <BR>    if (SurfaceMode)                    // 如果缓冲形式为:无缓冲页<BR>    {<BR>        selectpage(temp&gt;&gt;16);            // BIOS Video 换页<BR>        temp&amp;=0xffff;                    // 像素点相对 BIOS Video 页中的偏移<BR>        lastVpage=(temp&gt;&gt;16);<BR>        return (peekb(0xa000,temp));    // 获取BIOS Video当前页+偏移位置的颜色<BR>    }<BR>    else                                // 如果缓冲形式为:单缓冲页<BR>    {<BR>        nowEmap=temp&gt;&gt;14;                // 像素点位置转换成 EMS 逻辑页号<BR>        if (nowEmap!=lastEmap[0])<BR>            emap(nowEmap,0);            // 物理页号0和逻辑页号nowEmap建立映射关系<BR>        temp&amp;=0x3fff;                    // 像素点相对EMS逻辑页nowEmap的偏移<BR>        return(*(EmsPoint+temp));        // 获取(EMS基地址+偏移)位置的颜色<BR>    }<BR>}<BR><BR><BR>/***********************************************************************************************<BR>//    加载中文字体文件到EMS,初始化BMP图像数据区起始指针<BR>***********************************************************************************************/<BR>void LoadChinease() <BR>{<BR>    unsigned int i;<BR>    int HZK;<BR> <BR>    BmpStackStart=EMS_DATA_SEEK;<BR>    if ((HZK=_open("HZK12",1))!=-1)     // 加载HZK12点阵汉字库<BR>    {<BR>        for (i = 0 ; i &lt; 11 ; i++)<BR>        {<BR>            emap(80+i,0);                // EMS的80+i逻辑页和物理页0建立映射关系<BR>            _read(HZK,EmsPoint,16384);    // 读16K点阵字模到EMS的80+i逻辑页中<BR>        }<BR>        emap(80+i,0);                    // EMS的91逻辑页和物理页0建立映射关系<BR>        _read(HZK,EmsPoint,16048);        // 读最后15.7K点阵字模到EMS的80+11逻辑页中<BR>        HZK12_DATA+=EMS_DATA_SEEK;        // 修正HZK12的EMS数据指针    <BR>        BmpStackStart+=LENGTH_HZK12;<BR>        _close(HZK);                    // 关闭HZK12字库文件<BR>    }<BR>    if((HZK=_open("HZK16",1))!=-1)        // 加载HZK16点阵汉字库<BR>    {<BR>        if(HZK12_DATA&gt;0)                // 如果HZK12不空<BR>        {<BR>/********************************************************************************************************************************************<BR>//    由于读HZK12字库文件时,EMS第80+11逻辑页只读了16048字节,还剩下336字节,<BR>//    因此将HZK16字库文件的前336字节点阵字模读到第80+11逻辑页余下空间中<BR>********************************************************************************************************************************************/<BR>            _read(HZK,EmsPoint+16048,336);    // 读HZK16字库最初336字节点阵字模到EMS的91逻辑页剩余空间<BR>            for(i=0;i&lt;16;i++)<BR>            {<BR>                emap(92+i,0);            // EMS的92+i逻辑页和物理页0建立映射关系<BR>                _read(HZK,EmsPoint,16384);// 读16K点阵字模到EMS的92+i逻辑页中<BR>            }<BR>            emap(92+i,0);                // EMS的108逻辑页和物理页0建立映射关系<BR>            _read(HZK,EmsPoint,5136);    // 读HZK16字库最后5136点阵字模到EMS的108逻辑页<BR>            HZK16_DATA+=HZK12_DATA+LENGTH_HZK12;// 修正HZK16的EMS数据指针<BR>        }<BR>        else                            // HZK12字库如果空<BR>        {<BR>            for (i=0;i&lt;16;i++)<BR>            {<BR>                emap(80+i,0);            // EMS的80+i逻辑页和物理页0建立映射关系<BR>                _read(HZK,EmsPoint,16384);// 读HZK16字库文件16K点阵字模到EMS的80+i逻辑页中<BR>            }<BR>            emap(80+i,0);                // EMS的80+16逻辑页和物理页0建立映射关系<BR>            _read(HZK,EmsPoint,5472);    // 读HZK16字库文件5472字节点阵字模到EMS的96逻辑页中<BR>            HZK16_DATA=EMS_DATA_SEEK;    // 修正HZK16的EMS数据指针<BR>        }<BR>        BmpStackStart+=LENGTH_HZK16;<BR>        _close(HZK);                    // 关闭HZK16字库文件<BR>    }<BR>}<BR><BR><BR>/***********************************************************************************************<BR>//    清屏函数<BR>//    由于640*480=307200/1024=300K/64=5页<BR>//    入口参数:color = 清屏颜色<BR>***********************************************************************************************/<BR>void cls(unsigned char color)   <BR>{<BR>    register unsigned int i,n;<BR>    register char buffer[1024],*p=MK_FP(0xa000,0);<BR> <BR>    memset(buffer,color,1024);<BR>    if(SurfaceMode)                        // 如果缓冲形式为:无缓冲页<BR>    {<BR>        for (n = 0 ; n &lt; 5 ; n++)<BR>        {<BR>            selectpage(n);                // 选择BIOS Video n页(n=0-4)    <BR>            for(i=0;i&lt;64;i++)            // BIOS Video每页64K<BR>                memcpy(p+i*1024,buffer,1024);// 每次给VRAM送1K<BR>              //movedata(FP_SEG(buffer),FP_OFF(buffer),0xa000,i*1024,1024);<BR>        }<BR>    }<BR>    else                                // 如果缓冲形式为:单缓冲页<BR>    {<BR>        for(n = 0 ; n &lt; 300 ; n++)        // 640X480X256色共需300K,共计容纳19个EMS逻辑页<BR>        {<BR>            i=n/16;                        // EMS每个逻辑页为16K<BR>            if (n%16==0)<BR>                emap(i,0);                // 当i为16的整数倍则逻辑页i和物理页0建立内存映射关系<BR>//*********************************************************************************************************************<BR>//    依次将buffer中存储的1024字节清屏颜色送到EMS空间:EmsPoint + i*1024(i=0-15),其中EmsPoint为EMS空间基地址<BR>//*********************************************************************************************************************<BR>            memcpy(EmsPoint+n%16*1024l,buffer,1024);// 将buffer数组中存储的清屏颜色送至EMS空间,每次送1024字节<BR>        }<BR>    }<BR>}</P>
<P><BR>/***********************************************************************************************<BR>//    Video Bios 换页函数<BR>***********************************************************************************************/<BR>selectpage(register char page) <BR>{<BR>    union REGS r;<BR> <BR>    r.x.ax=0x4f05;<BR>    r.x.bx=0;<BR>    r.x.dx=page;                        // 选择页面<BR>    int86(0x10,&amp;r,&amp;r);<BR>    lastVpage=page;<BR>}</P>
<P>/***********************************************************************************************<BR>//    刷新页面(将EMS存储的信息写到VRAM屏幕上)<BR>//    对于640X480X256色需要5页VRAM;对于800X600X256色需要8页VRAM<BR>***********************************************************************************************/<BR>void vpost(void)    <BR>{<BR>    register unsigned int i,j;<BR> <BR>    if (!SurfaceMode)                    // 如果缓冲形式为:单缓冲页<BR>    {<BR>        for (j = 0 ; j &lt; 5 ; j++)        // 640X480X256共计5页BIOS Video<BR>        {<BR>            for (i = 0 ; i &lt; 4 ; i++)    // 1页EMS为16K,1页BIOS Video为64K<BR>                emap(j*4+i,i);            // EMS逻辑页j*4+i和物理页i建立内存映射关系<BR>            selectpage(j);                // BIOS Video 换页<BR>            memcpy(VPoint,EmsPoint,32768);// 拷贝EMS物理页0,1中存储的32K像素到显存前32K中<BR>            memcpy(VPoint+32768,EmsPoint+32768,32768);// 拷贝EMS物理页2,3中存储的32k像素到显存后32K中<BR>        }<BR>    }<BR>}</P>
<P><BR>/***********************************************************************************************<BR>//  单字节的图像数据字节传输函数,desc(目标)和src(源)均为传输的EMS相对偏移<BR>//    功能:将EMS空间中的单字节传输到VRAM(BIOS Video)。<BR>//    dest: 目标EMS相对偏移<BR>//    src : 源EMS相对偏移<BR>//  mode&gt;=0          :使用mode颜色掩码(过滤掉mode颜色)<BR>//  mode=COPY_PUT :直接传输(也可以换OR_PUT等)<BR>***********************************************************************************************/<BR>void byte_emstov(unsigned long desc,unsigned long src,char mode)<BR>{<BR>    register unsigned int vpage=desc&gt;&gt;16,        // 目标转换成BIOS Video页号<BR>                          voffset=desc&amp;0xffff,    // 目标相对VRAM页的偏移<BR>                             emsmap=src&gt;&gt;14,        // 源转换成EMS逻辑页号<BR>                          emsoffset=src&amp;0x3fff;    // 源相对逻辑页的偏移<BR>    register unsigned char c1,c2;</P>
<P>    if(lastEmap[0]!=emsmap)<BR>        emap(emsmap,0);                    // EMS逻辑页emsmap和物理页号0建立内存映射关系<BR>    if(lastVpage!=vpage)<BR>        selectpage(vpage);                // BIOS Video 换页<BR>    c1=*(VPoint+voffset);                // 取目标位置像素点颜色<BR>    c2=*(EmsPoint+emsoffset);            // 取源位置像素点颜色<BR>    if (mode&gt;=0)<BR>    {<BR>        if (c2!=mode)<BR>            *(VPoint+voffset)=c2;        // (源)直接传输模式<BR>    }<BR>    else<BR>    {<BR>        switch(mode)<BR>        {<BR>            case COPY_PUT    :*(VPoint+voffset)=c2;break;// (源)直接传输模式<BR>            case INVERT_PUT  :*(VPoint+voffset)=~c2;break;// (源)取反模式<BR>            case OR_PUT      :*(VPoint+voffset)=c1|c2;break;// (源和目标)或模式<BR>            case AND_PUT     :*(VPoint+voffset)=c1&amp;c2;break;// (源和目标)与模式<BR>            case XOR_PUT     :*(VPoint+voffset)=c1^c2;break;// (源和目标)异或模式<BR>            default             :*(VPoint+voffset)=c2;break;// (源)直接传输模式<BR>        }<BR>    }<BR>}</P>
<P><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>}</P>

lyood 发表于 2007-1-10 15:55

[em01]辛苦了~~

feixiang569 发表于 2007-4-1 09:59

<P>多谢了![em08]</P>

页: [1]

编程论坛