hsbnetsh 发表于 2007-4-20 19:47

[求助]PC104人机界面编程,TP6508IQ显示芯片,如何显示640*480*256画面

大家好,偶是个新人,最近使用嵌入式PC104做项目,该机器使用的是台湾凌越(TOPRO)的TP6508IQ显示芯片,<BR>我在普通PC机的TC2.0下编写的640*480*256色画面,在该PC104上就无法正常显示,<BR>而很多高分辨率画面在该系统上更是无法显示,<BR>我在网络上也搜索不到针对这种显示芯片的例程,<BR>看到咱们这里很多热心的高手前辈,所以我想到这里来向大家请教,<BR>希望有PC104编程经验的前辈们不吝赐教,万分感谢!<BR><BR>PS:偶前几天发的关于SVGA256.BGI问题的帖子,还请前辈们多多指点.<BR>[求助]在使用SVGA256.BGI后,TC2.0中的setacivepage()函数还能使用么?<BR><a href="http://bbs.bc-cn.net/viewthread.php?tid=132901" target="_blank" >http://bbs.bc-cn.net/viewthread.php?tid=132901</A><BR>[求助]寻求SVGA256.BGI相关的技术文档,谢谢大家<BR><a href="http://bbs.bc-cn.net/viewthread.php?tid=132826" target="_blank" >http://bbs.bc-cn.net/viewthread.php?tid=132826</A>

ba_wang_mao 发表于 2007-4-23 16:09

<P>做嵌入式最好自己编写底层驱动程序,仔细研究这个网站上提供的<NEO>、<VGA13h>、<jsk>源码,肯定能编写出800*600甚至1024*768图形驱动程序的。<BR><BR>以下是我的部分源码</P>
<P>#define VRAM_GRAPH_800X600X256(x,y)    (((unsigned long)y&lt;&lt;9L)+((unsigned long)y&lt;&lt;8L)+((unsigned long)y&lt;&lt;5L)+((unsigned long)(x)))<BR>void far (*XMS_Function)(void) = 0L;// XMS服务程序入口地址<BR>XMS_HANDLE xms_handle;                // 伪指针<BR>int g_cur_vbe_page = 0;<BR>int GUI_SP = 0;                        // 弹出式堆栈指针<BR>unsigned char far *ROM_ASCII;<BR>int Back_Color,Fore_Color,Fill_Color;<BR>struct XMS xms;<BR><BR>//    设置 bar 填充颜色(同 Turbo C)<BR>void _Cdecl setfillstyle(int __pattern,int color)<BR>{<BR>    __pattern++;                    // no use<BR>    Fill_Color = color;<BR>}</P>
<P>//    设置前景色(同 Turbo C)<BR>void _Cdecl setcolor(int color)<BR>{<BR>    Fore_Color = color;<BR>}</P>
<P><BR>//    获取前景色(同 Turbo C)<BR>int _Cdecl getcolor(void)<BR>{<BR>    return (Fore_Color);<BR>}</P>
<P><BR>//    设置背景色(同 Turbo C)<BR>void _Cdecl setbkcolor(int color)<BR>{<BR>    Back_Color = color;<BR>}</P>
<P>//    获取背景色(同 Turbo C)<BR>int _Cdecl getbkcolor(void)<BR>{<BR>    return (Back_Color);<BR>}</P>
<P><BR>//    获取填充色<BR>int _Cdecl getfillcolor(void)<BR>{<BR>    return (Fill_Color);<BR>}</P>
<P><BR>//检测XMS是否安装<BR>BOOL _Cdecl XMS_Test(void)<BR>{<BR>    _AX = 0x4300;<BR>    __int__(0x2F);<BR>    if (_AL == 0x80)            //    检查XMS驱动程序是否已经安装<BR>    {<BR>        _AX = 0x4310;<BR>        __int__(0x2F);            //    取得XMS功能调用的地址<BR>        XMS_Function=(void far *)MK_FP(_ES,_BX); //    返回值:ES:BX -&gt; 驱动程序入口地址<BR>        return (TRUE);<BR>    }<BR>    return (FALSE);<BR>}</P>
<P><BR>//    说明: 获取XMS驱动器版本号<BR>unsigned int _Cdecl XMS_Version(void)<BR>{<BR>    _AH = 0x00;<BR>    (XMS_Function)();<BR>    return (_AX);<BR>}</P>
<P><BR>//查询空闲的扩充内存空间(不包括HMA)<BR>int _Cdecl XMS_Size(void)<BR>{<BR>    _AH = 0x08;<BR>    XMS_Function();<BR>    return (_DX);<BR>}</P>
<P><BR>//分配扩充内存<BR>int _Cdecl XMS_Alloc(int size)<BR>{<BR>    _DX = size;                    //    扩充内存块大小,单位为K字节<BR>    _AH = 0x09;<BR>    XMS_Function();<BR>    if(_AX == 1)<BR>        return (_DX);<BR>    return (0x00);<BR>}</P>
<P><BR>//    为句柄重新分配内存<BR>int _Cdecl XMS_ReAlloc(XMS_HANDLE handle,int resize)<BR>{<BR>    _AH = 0x0F;<BR>       _DX = handle;<BR>    _BX = resize;<BR>    (XMS_Function)();<BR>    if (_AX)<BR>    {<BR>        XMS_Size();<BR>        return (handle);<BR>    }<BR>    return (-1);<BR>}</P>
<P><BR>//    释放指定句柄所分配的扩充内存<BR>BOOL _Cdecl XMS_Free(XMS_HANDLE handle)<BR>{<BR>    _DX = handle;<BR>    _AH = 0x0A;<BR>    XMS_Function();<BR>    if(_AX)<BR>        return (TRUE);<BR>    return (FALSE);<BR>}</P>
<P><BR>//扩充内存和常规内存中的数据交换(移动扩充内存块)<BR>//    移动扩充内存块<BR>//  输入参数:<BR>//        AH = 0Bh<BR>//      DS:SI -&gt; XMS 结构<BR>//  返回值:<BR>//        AX = 0001h 成功<BR>//         = 0000h 失败<BR>//      BL = 错误代码<BR>//  注: 如果结构中任一句柄为0000h, 那么其对应32位偏移量将被视为常规内存的绝对地址<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>BOOL _Cdecl XMS_Move(struct XMS *xms)<BR>{<BR>    _DS = FP_SEG(xms);<BR>    _SI = FP_OFF(xms);<BR>    _AH = 0x0B;<BR>    XMS_Function();<BR>    if (_AX)<BR>        return (TRUE);<BR>    return (FALSE);<BR>}</P>
<P><BR>//将汉字库点阵字模从常规内存缓冲区buf装载到扩充内存<BR>void _Cdecl Write_To_XMS(char *buf,unsigned int size,XMS_HANDLE handle,unsigned long offset)<BR>{<BR>    xms.length = size;<BR>    xms.source_handle = 0;<BR>    xms.source_offset  = FP_SEG((void far *)buf);<BR>    xms.source_offset &lt;&lt;= 16;<BR>    xms.source_offset += FP_OFF((void far *)buf);<BR>    xms.dest_handle = handle;<BR>    xms.dest_offset = offset;<BR>    XMS_Move(&amp;xms);<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//从扩充内存中读取汉字点阵字模到常规内存缓冲区buf<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl Read_From_XMS(char *buf,unsigned int size,XMS_HANDLE handle,unsigned long offset)<BR>{<BR>    xms.length = size;<BR>    xms.source_handle = handle;<BR>    xms.source_offset = offset;<BR>    xms.dest_handle = 0;<BR>    xms.dest_offset = FP_SEG((void far *)buf);<BR>    xms.dest_offset &lt;&lt;= 16;<BR>    xms.dest_offset  += FP_OFF((void far *)buf);<BR>    XMS_Move(&amp;xms);<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//汉字库点阵装载到扩充内存<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl ReadHzkXMS(char *Hzk16)<BR>{<BR>    unsigned long hzksize;<BR>    unsigned int size;<BR>    unsigned long offset = 0;<BR>    char buf[32];<BR>    FILE *fp;</P>
<P>    if (!XMS_Test())<BR>    {<BR>        puts("not found XMS");<BR>        exit(1);<BR>    }<BR>    if ((fp = fopen(Hzk16,"rb")) == NULL)<BR>    {<BR>        puts("Cannot Open HZK16 ...\n");<BR>        exit(1);<BR>    }<BR>    fseek(fp,0L,SEEK_END);<BR>    hzksize = ftell(fp);<BR>    fseek(fp,0L,SEEK_SET);<BR>    size = (int)(hzksize&gt;&gt;10) +1;<BR>    if (XMS_Size() &lt; size)<BR>    {<BR>        puts("not enough XMS");<BR>        fclose(fp);<BR>        exit(-1);<BR>    }<BR>    if ((xms_handle = XMS_Alloc(size)) == 0)<BR>    {<BR>        puts("XMS handle Error...");<BR>        fclose(fp);<BR>        exit(-1);<BR>    }<BR>    while (!feof(fp))<BR>    {<BR>        size = fread(buf,sizeof(char),32,fp);<BR>        Write_To_XMS(buf,size,xms_handle,offset);<BR>        offset += size;<BR>    }<BR>    fclose(fp);<BR>    ROM_ASCII = Current_ASCII_ROM(S16X8);<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//    释放XMS内存<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl HzkFree(void)<BR>{<BR>    XMS_Free(xms_handle);<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//    汉字点阵字模从XMS读到缓冲区buf中<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl ReadHzkBit(unsigned char *qw,unsigned char *buf)<BR>{<BR>    unsigned short QM,WM;<BR>    long offset;</P>
<P>    QM = *qw - 160;<BR>    WM = *(qw+1) - 160;<BR>    offset = ((QM-1)*94+WM-1)*32L;<BR>    Read_From_XMS(buf,32,xms_handle,offset);<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//获得 ASCII ROM字符集首址<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>unsigned char far *Get_ASCII_ROM(unsigned int BX)<BR>{<BR>    _AX = 0x1130;<BR>    _BX = BX;<BR>    __int__(0x10);<BR>    return (unsigned char far *)MK_FP(_ES,_BP);</P>
<P>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//获得 8X8或14X8或16X8英文字模基地址<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>unsigned char far  *Current_ASCII_ROM(int ch)<BR>{<BR>    switch(ch)<BR>    {<BR>        case S8X8:<BR>            return (Get_ASCII_ROM(0x0300));<BR>        case S14X8:<BR>            return (Get_ASCII_ROM(0x0200));<BR>        case S16X8:<BR>            return (Get_ASCII_ROM(0x0600));<BR>        default:<BR>            return (Get_ASCII_ROM(0x0600));<BR>    }<BR>}</P>
<P><BR> </P>

ba_wang_mao 发表于 2007-4-23 16:09

<P>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//显存换页函数<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl set_vbe_page(int page)<BR>{<BR>    if (g_cur_vbe_page != page)<BR>    {<BR>        _BX = 0;<BR>        _DX = g_cur_vbe_page = page;<BR>        _AX = 0x4F05;<BR>        __int__(0x10);<BR>    }<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//读像素点函数<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>char _Cdecl GetPixel(int x, int y)<BR>{<BR>    long addr;<BR>    int  page;<BR>    char far *videoptr = (char far *)0xa0000000L;</P>
<P>    addr = VRAM_GRAPH_800X600X256(x,y);<BR>    page = (int)(addr &gt;&gt; 16);<BR>    set_vbe_page(page);<BR>    return *(videoptr + (unsigned)(addr &amp; 0xffff));<BR>//  return (peekb(0xa000, (unsigned)(addr &amp; 0xFFFF) ));<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//画点函数<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl PutPixel(int x,int y,int color)<BR>{<BR>    int page;<BR>    long addr;<BR>    char far *videoptr = (char far *)0xa0000000L;</P>
<P>    if (x &lt; 800 &amp;&amp; y &lt; 600)<BR>    {<BR>        addr = VRAM_GRAPH_800X600X256(x,y);<BR>        page = (int)(addr &gt;&gt; 16);<BR>        set_vbe_page(page);<BR>//        pokeb(0xa000, (unsigned)(addr &amp; 0xFFFF),color);<BR>        *(videoptr+(unsigned int)(addr&amp;0xffff))= color;<BR>    }<BR>}</P>
<P>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////绘制一条垂直线函数<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl Vline(int x, int y1, int y2)<BR>{<BR>    int i,gcolor = getcolor();</P>
<P>    for (i = y1; i &lt;= y2; ++i)<BR>        PutPixel(x,i,gcolor);<BR>}</P>

<P>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////绘制一条水平线函数<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl Hline(int x1, int y, int x2)<BR>{<BR>    int i,gcolor = getcolor();</P>
<P>    for (i=x1;i&lt;=x2;i++)<BR>        PutPixel(i,y,gcolor);<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////通用画线子程序<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl Line(int x1,int y1,int x2,int y2)<BR>{<BR>    register int t,d;<BR>    int xer=0,yer=0,deta_x,deta_y,incx,incy;<BR>    int gcolor = getcolor();</P>
<P>    deta_x = x2 - x1;<BR>    deta_y = y2 - y1;<BR>    if (deta_x&gt;0)<BR>       incx = 1;<BR>    else if(deta_x == 0)<BR>        incx = 0;<BR>    else<BR>        incx = -1;<BR>    if (deta_y&gt;0)<BR>        incy = 1;<BR>    else if (deta_y == 0)<BR>        incy = 0;<BR>    else<BR>        incy = -1;</P>
<P>    deta_x = abs(deta_x);<BR>    deta_y = abs(deta_y);</P>
<P>    if (deta_x&gt;deta_y)<BR>        d = deta_x;<BR>    else<BR>        d = deta_y;</P>
<P>    for (t=0;t&lt;=d+1;t++)<BR>    {<BR>        PutPixel(x1,y1,gcolor);<BR>        xer += deta_x;<BR>        yer += deta_y;<BR>        if (xer&gt;d)<BR>        {<BR>            xer -= d;<BR>            x1 += incx;<BR>        }<BR>        if (yer&gt;d)<BR>        {<BR>            yer -= d;<BR>            y1 += incy;<BR>        }<BR>    }<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////画矩形<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl Rectangle(int x1,int y1,int x2,int y2)<BR>{<BR>    Hline(x1, y1, x2);<BR>    Hline(x1, y2, x2);<BR>    Vline(x1, y1, y2);<BR>    Vline(x2, y1, y2);</P>
<P>}</P>

<P>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////填充矩形<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl Bar(int x1, int y1, int x2, int y2)<BR>{<BR>    int i,gcolor = getcolor();</P>
<P>    setcolor(Fill_Color);<BR>    for (i = y1; i &lt;= y2; ++i)<BR>        Hline(x1, i, x2);<BR>    setcolor(gcolor);<BR>}</P>

<P>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////画圆函数,以(c_x, c_y)为中心画一半径为r的圆<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl Circle(int c_x, int c_y, int r)<BR>{<BR>    int x = 0, y = r, d0, d1, d2, direction;<BR>    int gcolor = getcolor();</P>
<P>    d0 = (1-r) &lt;&lt; 1;<BR>    while (y &gt;= 0)<BR>    {<BR>        PutPixel(c_x + x, c_y + y, gcolor);<BR>        PutPixel(c_x - x, c_y - y, gcolor);<BR>        PutPixel(c_x + x, c_y - y, gcolor);<BR>        PutPixel(c_x - x, c_y + y, gcolor);<BR>        if (d0 &lt; 0)<BR>        {<BR>            d1 = ((d0 + y) &lt;&lt; 1) -1;<BR>            if (d1 &lt;= 0) direction = 1;<BR>            else direction = 2;<BR>        }<BR>        else if (d0 &gt; 0)<BR>        {<BR>            d2 = ((d0 - x) &lt;&lt; 1) - 1;<BR>            if (d2 &lt;= 0) direction = 2;<BR>            else direction = 3;<BR>        }<BR>        else direction = 2;</P>
<P>        switch(direction)<BR>        {<BR>            case 1 : ++x;<BR>                d0 += (x&lt;&lt;1) + 1;<BR>                break;<BR>            case 2 : ++x;<BR>                --y;<BR>                d0+=(x-y+1)&lt;&lt;1;<BR>                break;<BR>            case 3 : --y;<BR>                d0 += -(y&lt;&lt;1) + 1;<BR>                break;<BR>        }<BR>    }<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////填充的圆形,使用的是Midpoint算法<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl CircleFill(int x0, int y0, int r)<BR>{<BR>    int x,y;<BR>    int deltax,deltay;<BR>    int d,gcolor = getcolor();</P>
<P>    x = 0;<BR>    y = r;<BR>    deltax = 3;<BR>    deltay = 2 - (r &lt;&lt; 1);<BR>    d = 1 - r;</P>
<P>    setcolor(getfillcolor());<BR>    while (x &lt;= y)<BR>    {<BR>        Hline(x0-x, y0+y, x0+x) ;<BR>        Hline(x0-x, y0-y, x0+x);<BR>        Hline(x0-y, y0-x, x0+y);<BR>        Hline(x0-y, y0+x, x0+y);<BR>        Hline(x0-x, y0+y, x0+x);<BR>        if(d&lt;0)<BR>        {<BR>            d += deltax;<BR>            deltax += 2;<BR>            x++;<BR>        }<BR>        else<BR>        {<BR>            d += deltax+deltay;<BR>            deltax += 2;<BR>            deltay += 2;<BR>            x++;<BR>            y--;<BR>         }<BR>    }<BR>   setcolor(gcolor);<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////图形模式初始化子程序<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl InitGraph(void)<BR>{<BR>    _AX = 0x4F02;<BR>    _BX = VBE800X600X256;<BR>    __int__(0x10);<BR>    if (_AH != 0)<BR>    {<BR>        puts("Can't Initialize the graphics mode!");<BR>        exit(1);<BR>    }<BR>}</P>
<P>//////////////////////////////////////////////////////////////////////////////<BR>////关闭图形模式,回到文本模式子程序<BR>//////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl CloseGraph(void)<BR>{<BR>    _AX = 0x4F02;<BR>    _BX = 0x03;<BR>    __int__(0x10);<BR>}</P>

ba_wang_mao 发表于 2007-4-23 16:13

<P>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>////中英文混合输出函数<BR>////unsigned char mat[16][2],<BR>////for(j=0;j&lt;16;j++)<BR>////        for(i=0;i&lt;2;i++)<BR>////            for(k=0;k&lt;8;k++)<BR>////                if(mat[j][i]&amp;(0x80&gt;&gt;k)) /*测试为1的位则显示*/<BR>////                    putpixel(i*8+k,j,WHITE);<BR>//// x,y =坐标<BR>////p = 中英文混合字符串<BR>////d=字符之间的间距,以像素为单位<BR>///color = 字符颜色<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void _Cdecl puthz(int x,int y,char *p,int color,int d)<BR>{<BR>    unsigned int i,j;<BR>    unsigned char ch;<BR>    unsigned char matrix[32];<BR>unsigned char far *ROM_ASCII;<BR></P>
<P>    while((ch=*p++)!=0)<BR>    {<BR>        if(ch&gt;160)<BR>        {<BR>            p--;<BR>            ReadHzkBit(p,matrix);<BR>            for(j = 0 ; j &lt; 16 ; j++)<BR>                for(i = 0 ; i &lt; 16 ; i++)<BR>                    if(matrix[2*j+i/8] &amp; (0x80&gt;&gt;i%8))<BR>                        PutPixel(i+x,y+j,color);<BR>                    else<BR>                        PutPixel(i+x,y+j,Back_Color);<BR>            p++;<BR>            p++;<BR>            x+=16+d;<BR>        }<BR>        else<BR>        {<BR>            ROM_ASCII = Current_ASCII_ROM(S16X8);//从PC机ROM中提取英文16X8点阵字模<BR>            for(i=0;i&lt;16;i++)<BR>            {<BR>                matrix[i*2]=*(ROM_ASCII+(ch)*16+i);<BR>                matrix[i*2+1]=0;        //    字模右边8位补0<BR>            }<BR>            for(j=0;j&lt;16;j++)<BR>                for(i=0;i&lt;8;i++)<BR>                    if (matrix[2*j+i/8] &amp; (0x80&gt;&gt;i%8))<BR>                       PutPixel(i+x,y+j,color);<BR>                    else<BR>                       PutPixel(i+x,y+j,Back_Color);<BR>            x+=8+d;<BR>/*-----------------------------------------------------------------------------------------------*/<BR>//    如果采用8X8点阵字模显示英文及数字,请采用如下代码<BR>/*-----------------------------------------------------------------------------------------------*/<BR>/*            for(i=0;i&lt;8;i++)<BR>                buf[i]=*(ROM_ASCII+(ch)*8+i);<BR>            for(j=0;j&lt;8;j++)<BR>                for(i=0;i&lt;8;i++)<BR>                    if((0x80&gt;&gt;i%8)&amp;buf[j+i/8])<BR>                        POPUP_PutPixel(i+x,y+j+5,color);<BR>                    else<BR>                        POPUP_PutPixel(i+x,y+j+5,Back_Color);<BR>            x+=8+d;*/<BR>        }<BR>    }<BR>}<BR></P>

页: [1]

编程论坛