精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>C/C++>>DOS编程>>dos里显示汉字的问题

主题:dos里显示汉字的问题
发信人: wangbingboy()
整理人: wenbobo(2002-08-13 10:45:44), 站内信件
前两天在一本书中看到C在图形下显示汉字,用TC2。0编译成功,我想在文
本方式下输出,不知应如何做呢?

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.97.186.69]
发信人: pazee (耙子), 信区: CLanguage
标  题: Re: 一个关于汉字显示的问题
发信站: 网易虚拟社区 (Thu Dec  9 19:09:07 1999), 站内信件

【 在 wangbingboy (冰) 的大作中提到: 】
: 前两天在一本书中看到C在图形下显示汉字,用TC2。0编译成功,我想在文
: 本方式下输出,不知应如何做呢?

有很多在文本输出的例子,如当年的洪涛软件就有很多这么做的,现在的kv300
都是,还有著名的norton,pcshell,cpav等等,尤其他们的鼠标模拟的很有特色
还有一些dos文本下的英汉辞典,大致的原理就是替换字符点阵信息,vga模式的
每个字符显示为9*16,他的点阵字库固化在显示卡的rom中,通常有几套字符集.
显示卡初始化后把一套字符的点阵装入ram(这就为我们的修改提供了便利),
点阵的大小是8*16存放的,也就是说只能放半个汉字的点阵,当字符的asc码
位于造表符那一段(具体的我忘了),显示时会把地8列复制到第9列,这样
就不会出现造表符的断裂,(有些汉字看起来中间的竖要粗,就是这个原因)
正常是第九列是空的,作为字符的分割,所以,能用来改造显示汉字的只有
原来存放造表符的位置,当然,其他的也行,但是原则上不能占用127以下
的asc码,否则正常的显示就不行了,另外,汉字的横也会出现断裂,在一些
英汉辞典中能看到断裂现象大约一个屏幕同时可显示几十个不同汉字.
在int 10h里面有个子功能号是可以写存放在ram的字符点阵的,把你要显
示的汉字点阵信息替换进去,打个比方你把造表符的 "-"、"|"分别替换成了
“显”的左半边和右半边的点阵信息,当你要显示"显"字时,你只需显示
"-|"就是了。原理就是这样。
只有vga和以上的显示模式才会把点阵信息写入ram.cga,ega方式下是不行的。
当你用int 10h设置显示模式时,(vga 80*25*16大概是3号模式)显示卡回
复位你修改的点阵字库,所以,要在设置显示模式完成后,才能替换字库,
否则就白辛苦了。
我大二的时候写过类似的程序,现在都记不得了,我很愿意和你共同探讨一下。

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
别人睡觉我站着,别人吃饭我看着.

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.191.124]
发信人: riffle (钢狼), 信区: CLanguage
标  题: Re: 一个关于汉字显示的问题
发信站: 网易虚拟社区 (Fri Dec 10 09:53:47 1999), 站内信件

【 在 pazee (耙子) 的大作中提到: 】
: 【 在 wangbingboy (冰) 的大作中提到: 】
: : 前两天在一本书中看到C在图形下显示汉字,用TC2。0编译成功,我想在文
: : 本方式下输出,不知应如何做呢?

:    .......

    汉字的显示,使用ROM中的字模好象行不同,例如0xb0,0xa1
表示“啊”,而0xb1,0xa1则表示“薄”,对于这两个字的0xa1是
显示“啊”的右半部分还是显示“薄”的右半部分呢?

    其实,DOS下很多汉字系统的的方法都是这样的:截获时钟中
断(INT 8H 或 1CH),在时钟中断服务程序里将显存中的内容以
图形显示模式绘制出来,末了再恢复显示模式为3(文本模式)。不
过,它们一般还要进行一点技术处理,因为在改变显示模式的时候,
屏幕上的显示内容会被清除掉,所以应加上不清除屏幕显示内容的
限制,就达到目的了。

   这点可以通过两个测试验证:
     1、在DOS汉字环境下,用C编一个绘图程序,结果发现,明明进
入了图形模式,后来却又回到了文本模式(如果用printf显示了汉字
的话)。
     2、仍在DOS汉字环境下,编一个驻留程序截获时钟中断(最
好是INT 8),并故意在时钟中断服务程序里拖延时间。驻留程序
返回到DOS提示符下,仍在起作用,这时候执行DIR命令,就会发现
屏幕的刷新是一阵一阵的。甚至还出了点错误:本该在屏幕底部的
内容跑到屏幕顶部了。

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.37.129]
发信人: pazee (耙子), 信区: CLanguage
标  题: Re: 一个关于汉字显示的问题
发信站: 网易虚拟社区 (Fri Dec 10 16:26:45 1999), 站内信件

【 在 riffle (钢狼) 的大作中提到: 】
: 【 在 pazee (耙子) 的大作中提到: 】
: : 【 在 wangbingboy (冰) 的大作中提到: 】
: : 
: :    .......
:    .......

你可能没有明白,所谓在文本方式下显示汉字通常汉字的编码是自定义的,
我通常生成一个小字库,汉字编码自己定义,不用国标码.这并不是你说的什么
"阿"1601的问题,你在用kv300杀毒时可能发现文件名是汉字的在存文本下是
乱码,但有时是半个汉字,这就是因为替换字符点阵的原因.
另外,你认为在图形模式下就不能用printf了吗?其实是一样的.puts也能用.
文本的光标是硬件产生的,在图形模式下没有,你可以通过这个简单的判断
得知你的工作方式.ucdos的光标是用软件模拟的,你死机了光标也就不闪了,
在文本下死机了也会闪.
在早年的汉字系统spdos,ccdos他做的都是接管int 10h,这是显示中断的入口,
但是如pctool等直接写屏的就不能汉化了,因为直接写屏绕过了int 10h,而是
向文本显存b800:0000直接写文本内容.后来,倚天汉字\天汇\ucdos等采用了
接管int 8h.int 1ch的方法,定时的检测b800:0000的4K显存,在图形模式下
对应的位置画上汉字,这就解决了直接写屏的问题,在pctool下也可以看到汉字
了,如果你在刷新时按下pause,你可能会看到半个屏幕,或者错位的显示,这是
正常现象,因为他没有刷新完成,甚至有些位置来不及刷新完,新的又该刷新了.
(就像你说的延时\再dir)
你在ucdos下检测当前的显示模式,你会发现得到的是3(80*25*16文本),其实,
ucdos修改了0040:xxxx(大约是这段dos参数保存在这里),int 10h就是从这
里得到当前的显示模式的,在显示卡中通过设置寄存器已经成了图形了.
我大学是写过一个操作显示卡的tsr程序,通过直接写屏实现bar,cycle,line等
功能,证实过这点.
在文本下显示汉字和图形下完全不是一种概念,可以说文本下实现没有什么太大

的价值,但在技术上是可行的.和你说的完全不同.
显示卡对于图形和文本的缓存位置\方式都完全不同,而且也不能实现文本和图形

同时存在,感兴趣你可以翻翻vga的书.

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
别人睡觉我站着,别人吃饭我看着.

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.191.124]
发信人: riffle (钢狼), 信区: CLanguage
标  题: Re: 一个关于汉字显示的问题
发信站: 网易虚拟社区 (Fri Dec 10 17:37:59 1999), 站内信件

【 在 pazee (耙子) 的大作中提到: 】
: 【 在 riffle (钢狼) 的大作中提到: 】
: : 【 在 pazee (耙子) 的大作中提到: 】
: :    .......

:    .......
   1、我没有认为在图形模式下不可以用printf。
   2、我没有说要在文本方式下显示汉字。
   3、自己定义汉字编码不是很科学,对程序可维性和可扩充性不太好。

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.38.220]
发信人: pazee (耙子), 信区: CLanguage
标  题: Re: 一个关于汉字显示的问题
发信站: 网易虚拟社区 (Sun Dec 12 15:09:00 1999), 站内信件

【 在 riffle (钢狼) 的大作中提到: 】
: 【 在 pazee (耙子) 的大作中提到: 】
: : 【 在 riffle (钢狼) 的大作中提到: 】
: : 
: :    .......
:    .......

1.那我就不明白你上一篇文章的话了.
2.可是我们讨论的是在文本下显示汉字呀.
3.这里不是讨论编码科不科学的问题,而是在讨论技术的问题,
类似于早年的译临\既时通都是用的这个技术,因为前提条件
是要在纯文本上用.
用字定义字库,字定义汉字编码的主要目的在于减小字库的尺寸,现在的
ucdos不也有个脱离汉字的阅读器吗?可以把一个汉字文本变成exe,他
也用的小字库,因为一篇文章不可能把6763个gb码全用了,如果把120K的
字库加在exe里面,在dos来讲是件很可怕的事儿.
感兴趣的话你可以用td跟踪一下看看.你会发现这个技术很多人在用.

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
别人睡觉我站着,别人吃饭我看着.

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.191.124]
发信人: ikoo (找个地方好好玩), 信区: CLanguage
标  题: Re: 一个关于汉字显示的问题
发信站: 网易 BBS (Sun Dec 12 18:52:49 1999), 转信

佩服,我能问个不太相关的初级问题么?
我一直不太明白显示卡上比如12M显存的地址是怎样与系统内存的地址结合在一起的
呢?还是根本没结合完全是分开操作的?

【 在 pazee (耙子) 的大作中提到: 】
: 【 在 riffle (钢狼) 的大作中提到: 】
: : 【 在 pazee (耙子) 的大作中提到: 】
: :    .......

: 你可能没有明白,所谓在文本方式下显示汉字通常汉字的编码是自定义的,


--
※ 来源:.网易 BBS bbs.netease.com.[FROM: 202.104.185.21]
发信人: pazee (耙子), 信区: CLanguage
标  题: Re: 一个关于汉字显示的问题
发信站: 网易虚拟社区 (Mon Dec 13 09:33:10 1999), 站内信件

【 在 ikoo (找个地方好好玩) 的大作中提到: 】
: 佩服,我能问个不太相关的初级问题么?
: 我一直不太明白显示卡上比如12M显存的地址是怎样与系统内存的地址结合在一起的
: 呢?还是根本没结合完全是分开操作的?
: 【 在 pazee (耙子) 的大作中提到: 】
:    .......

非常不好意思,现在的显示卡发展的太快了,我也没太仔细研究,(设备无关性吗 :
-))
早年的显示卡能有1M,就已经了不得了,通常为256K或者512K(我编程的那个年代)

至于目前的agp我就更只知道个泛泛了.
我胡说几句,希望大家批评斧正.
我只熟悉dos下的
对于显示卡的编址,在各个模式下很混乱,早年的文本只需要 80*25*2Byte就足够
了,
因为最早的8086/8088只有20根地址线(寻址1M),而机器中只有640K, RAM,(人们当

没想到pc的内存会变成现在的大小)640~1023K这384K就成了系统用的了,显示卡也

用的这段空间,文本b800:0000开始的4K,随后有了图像模式CGA(320*200*2或者32
0*200*4)
他大概是从a000:0000开始的,连续存放,每个字节的高4位和低4位给代表一个点,
4位可以
表示16色,所以CGA下用的此显存也不过320*200*4/8 = 32K bytes(大约),
但到了vga(640*480*16)就要占用640*480*16/8 = 154K(大约),这超过了DOS下段
64K的限制,
所以vga采用了分页的办法,每个点16色,占用4各字节,分成4个页面,每个页面就都
小于64K了,
每层页面纪录一种颜色,就是4层16色了.每层的地址在pc里面是相同的a000:0000
,通过操作显
示卡的寄存器可以写不同的层.这种,这种VGA的标准模式流行了好久.(你可能会发
现文本用的
b800:0000也会被vga覆盖,就是说用图形模式就不能直接写屏了,那ucdos怎么办,
其实,他们
通过修改vga寄存器,成功的使vga不用b800:0000这4k,具体细节较复杂)
后来大量采用了640*480*256的方式,他每个点占用一个字节,而且也采用了连续地
址,但他依
然没有超过384K这个屏障,在real mode 下仍可以访问(地址编码在1M内,寻址范围
太小是dos致命的弊端),
后来到了16位色,24位,32位色你可以算算他们占用的空间远超过1M了,所以这些模
式在real mode
下就不能用到了.所以你可以看到著名的sea(dos看图的)用到了DOS4GW(使cpu变成
保护模式,这时
寻址能到2^24byte=16M),而后来到了增强模式cpu可以寻址2^32=4G了(这个4G是目
前32位pc寻址
的最大范围,也是window 32编程受的限制,实际编程能用2G)
现在的显存大得多了,除了我们显示正常屏幕用的,可以直接寻址,其余的几乎都是
给2D,3D加速质材
库用的,编址方式我就不清楚了.
而且AGP还可以用内存存放质材库.
也就是说,显示卡一定会在pc ram中有段地址映射.这样才能读写显示卡.

也望高手指教.

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
别人睡觉我站着,别人吃饭我看着.

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.191.124]

[关闭][返回]