主题 : 让Windows 1.0x支持VGA分辨率
义务网评猿
级别: 论坛版主
UID: 50665
精华: 7
发帖: 2924
威望: 13 星
金钱: 385657 浮游币
贡献值: 8748 点
好评度: 10293 点
人气: 760 点
在线时间: 697(时)
注册时间: 2005-08-02
最后登录: 2020-12-17
楼主  发表于: 2011-08-27 01:28

让Windows 1.0x支持VGA分辨率

Windows 1.0x出来的时候,VGA并未定标准,因此M$并没有支持它。20多年后看来,EGA分辨率的Windows 1.0x是非常难看的(虽然这个分辨率在现代16:10或者16:9正方形像素显示的宽屏上的显示效果比4:3非正方形像素的EGA更正确)。怎样让它支持VGA呢?答案有两种。一是修改Windows 2.x的VGA驱动程序;二是将Windows 1.0x的EGA驱动程序改为支持VGA模式。
第一种方法我也试过,但是似乎有难以解决的逻辑问题存在(位图字体无法显示)。因此试试第二种。
首先最好取一个可以不安装而更改驱动程序的Windows 1.0x版本作为调试用。我使用了Windows 1.03 SDK中的debug版Windows 1.03内核,制作了一个这样的版本。


首先解决显示模式问题。DOS下切换显示模式有很多方法,最可靠和常用的方法是使用BIOS INT 10H中断的00号功能。这个调用相当简单,AH寄存器存显示模式,AL寄存器存00H,INT 10H即可。用反汇编器找到EGAHIRES.DRV(在“慢启动”免安装版本中的DISPLAY.DRV)中的此调用。


根据INT 10H文档(http://webpages.charter.net/danrollins/techhelp/0114.HTM),10H模式为EGA 640x350 16色。改为12H(VGA 640x480 16色)。后面那个CMP AL,10H也要改成12H,否则启动时切换显示模式会判定为切换失败而死机。
可以看到系统已进入VGA模式,但仍只能显示上半350像素,显示区域下方还有几行内容随鼠标移动而改变的花屏像素。缺Ρ﹁要修改。


驱动程序如何对GDI确定其显示模式呢?查找了一下Win3.1 DDK,发现了这个GDIINFO结构体,还有一个PBITMAP(硬件位图)结构体。

typedef struct tagGDIINFO {
   short int dpVersion;
   short int dpTechnology;
   short int dpHorzSize;
   short int dpVertSize;
   short int dpHorzRes;
   short int dpVertRes;
   short int dpBitsPixel;
   short int dpPlanes;
   short int dpNumBrushes;
   short int dpNumPens;
   short int futureuse;
   short int dpNumFonts;
   short int dpNumColors;
   unsigned short int dpDEVICEsize;
   unsigned short int dpCurves;
   unsigned short int dpLines;
   unsigned short int dpPolygonals
   unsigned short int dpText;
   unsigned short int dpClip;
   unsigned short int dpRaster;
   short int dpAspectX;
   short int dpAspectY;
   short int dpAspectXY;
   short int dpStyleLen;
   POINT dpMLoWin;
   POINT dpMLoVpt;
   POINT dpMHiWin;
   POINT dpMHiVpt;
   POINT dpELoWin;
   POINT dpELoVpt;
   POINT dpEHiWin;
   POINT dpEHiVpt;
   POINT dpTwpWin;
   POINT dpTwpVpt;
   short int dpLogPixelsX;
   short int dpLogPixelsY;
   short int dpDCManage;
   short int dpCaps1;
   long int dpSpotSizeX;
   long int dpSpotSizeY;
   short int dpPalColors;
   short int dpPalReserved;
   short int dpPalResolution;
} GDIINFO;

typedef struct tagPBITMAP {
   short bmType;
   short bmWidth;
   short bmHeight;
   short bmWidthBytes;
   BYTE bmPlanes;
   BYTE bmBitsPixel;
   long bmBits;
   long bmWidthPlanes;
   long bmlpPDevice;
   short bmSegmentIndex;
   short bmScanSegment;
   short bmFillBytes;
   short reserved1;
   short reserved2;
} PBITMAP;

两个结构体都包含了长、宽信息,2个连续的字长。对于640x350,最后按x86字节序拼成16进制应该是80 02 5E 01。
虽然Win3.1的显示模型和1.x相比已经有了巨大的变动,根据GDIINFO和PBITMAP结构在display.drv中都找不到完全对应的,但是80 02 5E 01却找到了2处。
干脆把这两处都改成80 02 E0 01,也就是640x480。
这下好,显示能扩展到屏幕底部了。但是,鼠标移动到350行以下时仍然不显示,而且350线下方仍然有一些花版的区域。


看来这有涉及逻辑的地方,我退缩了。
后来经过洋大人John Elliott的指点,才知道里面还有几处硬编码了屏幕高度和屏幕缓冲区大小,屏幕的乱区就是因为驱动用显存缓冲区后面的冗余空间做鼠标覆盖缓冲了。
这个减去屏幕高度应该是鼠标移动到350下面就不显示了。


把5E 01直接改为E0 01,鼠标就可以显示到350行以下去了。但是花屏区域仍然存在。
至于这个屏幕缓冲区大小,本来一开始也想到了的,但是思维被框死在按字节计算这个值(640x350x4位=112000字节)上了,结果居然是单个位面的大小28000字节(60 6D)。应该是EGA16色存储的4个位面是分开而不是交叉的,因此一次可以完整写一个位面。在这里找到这个:


没看明白这个call的用途,不过nop掉这个call,开菜单时鼠标轨迹就不擦掉了。看来果然这个和鼠标有关。改掉为38400字节( 00 96 )。
这样下来开菜单时鼠标箭头的背景就变成黑色了,估计是擦鼠标箭头读了更新后那一块地址上应有的内容作为鼠标箭头背景,而其实原有屏幕内容却还保存在原位置(就是那些花版的地方)。


继续查这个28000,还发现2处一样的指令。




但三处都修改后,花版仍然存在。几乎又要放弃的时候,偶然往后跟踪那三个鼠标相关的调用,都在其中某个子程序发现了一个奇怪的常数28160(00 6E)。


我没搞懂这的逻辑(汇编不好+没有Win1 DDK+Win3.1 DDK的实例显卡驱动没认真看过),但是直觉上认为这个28160就是28000加上两行(一行640位=80字节)。改成38400+2x640/8=38560(A0 96)呢?果断试试看。三处全部改完,好,奇迹发生,乱屏部分终于消失了。


总结一下,把EGAHIRES.DRV进行修改,先把INT 10H部分改掉(B8 10 00 CD 10改成B8 12 00 CD 10,下面的3C 10 B8 00 00 改成3C 12 B8 00 00),那一处硬编码改掉(81 E9 5E 01改成81 E9 E0 01),把所有的BF 60 6D替换为BF 00 96,81 C0 00 6E替换为81 C0 A0 96就能让这个EGA驱动变成VGA的了。
把安装盘里面的这个EGAHIRES.DRV如法炮制,就能制作出可以支持VGA的标准安装版Windows 1.0x。
直接修改装好的1.01的WIN100.BIN,也可以实现。而且这个改法对于Windows 1.01-1.04都有效。


虽然还没搞懂最后那几个关于鼠标描绘部分修改的逻辑,但是至少我们又研究出了微软都没有几个人还记得的东西。
下次有时间把Windows 2.1/286的VGA驱动改到Win1.03使用的方法也写一下(不完善,位图字体不能用)。
这里是改过的Windows 1.03 EGAHIRES.drv和改过的已安装版Windows 1.01(支持PS/2鼠标)的下载。
win103vgadrv.rar (10 K) 下载次数:8
WIN101_vga_installed.rar (502 K) 下载次数:10   
感谢 kalakala(尝试Hack Windows 2.0x 驱动的高人),John Elliott的支持和指教。
John Elliott还实现了SVGA 800x600x16色,写了自动补丁程序。请看:
http://www.seasip.info/Misc/win1.html
燃烧的热血。。
坚强的意志。。
造就了YKSOFT Systems
http://yksoft1.spaces.live.com
级别: 模拟小生
UID: 137415
精华: 0
发帖: 16
威望: 0 星
金钱: 2256 浮游币
贡献值: 0 点
好评度: 42 点
人气: 2 点
在线时间: 85(时)
注册时间: 2006-08-25
最后登录: 2020-02-09
沙发  发表于: 2011-08-27 20:07

楼主钻研精神可嘉