老文章档案 · 2003 年

图形显示方式屏幕的保存和恢复

破解教程 · 汇编专区 · 2003-10-15 · 作者:人气: · 出处:赢政天下整理收藏)

概述:

在程序中常常要暂时的保存图形显示方式屏幕上的内容,然后把自己的信息输出到屏幕上,结束后再恢复原来的屏幕内容,特别在内存驻留程序弹出一个窗口时更要用到,但是图形方式下显示缓冲区的容量巨大,在常用的 80 x 25 文本方式下,显示缓冲区仅大小仅为 80 x 25 x 2 = 4000 字节,而在模式 13H 320 x 200 x 256 色时为 320 x 200 = 64000 字节,现在常用的高彩色、真彩色下如 800 x 600 x 65535 色时为 800 x 600 x 2 = 960000 字节,涉及到如此大的数据量程序必须使用磁盘交换方法或用到 XMS 做为数据保存缓冲区,使编程复杂化。

本文用了 INT 10H 中不清除显示内存设置新显示模式的方法,使不管在什么显示方式下,用到的缓冲区大下都在 10K 左右,即使在 1024 x 768 x 16.7M 色也能正常保存。

本程序的适用范围为保存屏幕后自己的程序仅仅使用文本模式 3 的情况,如果要用到图形模式,那么还是要保存全部的显示缓冲区。在兼容性方面,由于使用 VESA 标准功能,在现在的 PCI/VESA 显示卡上都能正常运行,我发现唯一不能运行的是有一段时期生产的 TVGA 8900/9000 卡,因为此卡在 VESA 功能刚出现的时候生产,支持 VESA 的伪彩色显示模式,却又不支持很多其他的 VESA 功能。大家找到克服的方法告诉我一声。

本程序要用到的一些中断的说明如下:

INT 10H 的 00H 功能,设置显示模式:

功能

入口参数

出口参数

INT 10H 的 00H功能

设置显示模式

AH = 00H

AL = 模式(如果位 7 置位,则不清除显示缓冲区)

INT 10H 的 1BH 功能,检测是否 VGA 卡:

功能

入口参数

出口参数

INT 10H 的 1BH功能

取 VGA/MCGA 的功能、状态信息

AH = 1BH

AL = 1BH 成功(说明显示卡为 VGA 以上)

ES:DI 返回状态信息

BX = 0000

AL <> 1BH 非VGA/MCGA 显示卡

ES:DI 指向 64 字节缓冲区

INT 10H 的 1CH 功能,保存/恢复视频状态:

功能

入口参数

出口参数

INT 10H 的 1C00H 功能

返回状态缓冲区容量

AX = 1C00H

AL = 1CH 成功

BX = 需要的 64 字节块数目

INT 10H 的 1C01H 功能

保存视频状态

AX = 1C01H

ES:BX 指向缓冲区

INT 10H 的 1C02H 功能

恢复视频状态

AX = 1C01H

CX = 要求的状态

位 0 = 恢复视频硬件状态

位 1 = BIOS 数据区

位 2 = 彩色寄存器和 DAC 状态

ES:BX 指向缓冲区(用1C01H功能保存下来的)

INT 10H 的 4FH 功能,VESA 功能:

功能

入口参数

出口参数

INT 10H 的 4F00H功能

取显示卡 VESA 信息

AX = 4F00H

AL = 4FH 说明显示卡支持VESA

AH = 00H 成功

AH = 01H 失败

ES:DI 指向缓冲区 (256 字节)

AL <> 4FH 显示卡不支持VESA

INT 10H 的 4F05H功能

控制对 VESA 显示卡视频 RAM 的访问

BH = 00H 选视频内存窗口

DX = 视频内存窗口地址

AH = 00H 成功

AH = 01H 失败

BH = 01H 取视频内存窗口

AH = 00H 成功

DX = 视频内存窗口地址

AH = 01H 失败

INT 33H 的 16H/17H 功能,保存/恢复鼠标驱动程序状态:

功能

入口参数

出口参数

INT 33H 的 0015H功能

确定保存鼠标驱动程序状态所需

的空间

AX = 0015H

BX = 所需大小

INT 33H 的 0016H功能

保存鼠标驱动程序状态

AX = 0016H

BX = 缓冲区大小(用 0015H 获得)

ES:DX 指向缓冲区

INT 33H 的 0017H功能

恢复鼠标驱动程序状态

AX = 0017H

BX = 缓冲区大小(用 0015H 获得)

ES:DX 指向缓冲区

源程序:

;by Luo Yun Bin

;http://asm.yeah.net

;这个子程序用来检测显示卡的类型,鼠标状态等等

;在程序初始化时执行

;文中要用到的一些缓冲区请自己定义,注意大小!

flag db ? ;标志位,位 7 置 1 表示安装了鼠标

vga_type db ? ;显示卡类型

video_mode db ? ;显示模式

vga_win1 dw ? ;视频窗口,暂存 VESA 的窗口状态

vga_win2 dw ? ;

vga_win3 dw ? ;

...

TEST_VGA PROC

push 0 ;检测是否安装鼠标驱动程序

pop ds

cmp word ptr ds:[33h*4],0

jz no_mouse

or cs:flag,10000000b ;has mouse installed

no_mouse:

push cs

pop ds mov ah,1bh ;检测是否是 VGA 以上显示卡

xor bx,bx

mov di,offset file_end

int 10h

cmp al,1bh

jnz tv_no_vga mov ax,4f00h ;检测是否支持 VESA 功能

mov di,offset file_end

int 10h

cmp al,4fh

jz tv_is_vesa mov dx,3c4h ;检测是否 TVGA 9000 卡

mov al,0eh ;这一段是照抄的,找不到资料

out dx,al

inc dx

in al,dx

mov bl,al xor al,al

out dx,al

in al,dx

xchg al,bl

out dx,al test bl,2

jnz tv_is_tvga mov dx,3cdh ;检测是否 ET6000 卡

in al,dx

mov ah,al

mov al,11h

out dx,al

in al,dx

xchg ah,al

out dx,al cmp ah,11h

jz tv_is_tseng mov vga_type,4

ret

tv_is_vesa:

mov vga_type,1

ret

tv_is_tvga:

mov vga_type,2

ret

tv_is_tseng:

mov vga_type,3

ret

tv_no_vga:

int 20h ;非 VGA 卡退出

TEST_VGA ENDP

...

;================================================================

;保存显示缓冲区内容并设置新的显示模式到 80 x 25 文本 (模式 3)SAVE_SCR PROC push ds

push es test flag,10000000b ;见前面

jz ss_no_mouse mov ax,16h ;保存鼠标状态

mov dx,offset mouse_buffer

int 33h

ss_no_mouse:

mov ax,1c01h ;保存视频状态

mov bx,offset video_buffer

mov cx,7

int 10h mov ah,0fh ;保存原显示模式

int 10h

mov video_mode,al cmp al,3 ;80 x 25 x 16 色

jz ss_mode3

cmp al,7 ;80 x 25 黑白

jz ss_mode7 xor ax,ax ;以下为图形方式保存显示缓冲区

call vga_page

call vga_base

call save_vram mov ax,0083h ;设置新的显示模式,不清除显示内存

int 10h

push 0b800h

pop ds ;保存显示内存

xor si,si

mov cx,1000h

mov di,offset ram_buffer

push cs

push ds

cld

rep movsb xor di,di ;

mov cx,80*25

mov ax,57b1h ;填充背景,不然有乱字符

cld

rep stosw

scr_ret:

pop es

pop ds

ret

ss_mode3:

call save_vram ;显示模式 3 保存显示 RAM

jmp short scr_ret

ss_mode7:

push 0b000h ;显示模式 7 保存显示 RAM

pop ds

call save_vram1

mov ax,3

int 10h

call restore_vram

jmp short scr_retSAVE_SCR ENDPSAVE_VRAM PROC push 0b800h ;把显示内存保存到自己的缓冲区

pop ds

save_vram1:

push cs

pop ds

xor si,si

mov di,offset ram_buffer

mov cx,2000h

cld

rep movsb

ret

SAVE_VRAM ENDPRESTORE_VRAM PROC

push 0b800h ;恢复显示缓冲区内容

pop es

restore_vram1:

xor di,di

push cs

pop ds

mov si,offset ram_buffer

mov cx,2000h

cld

rep movsb

ret

RESTORE_VRAM ENDPVGA_PAGE PROC cmp vga_type,1

jnz other_vga1

cmp ah,1

jz vp_vesa2

cmp ah,2

jz vp_vesa1

mov ax,4f05h ;保存 VESA 显示卡状态

mov bx,0100h

int 10h

mov vga_win1,dx

mov ax,4f05h

mov bx,0101h

int 10h

mov vga_win2,dx

vp_vesa1:

mov ax,4f05h

xor bx,bx

xor dx,dx

int 10h

mov ax,4f05h

mov bx,0001h

xor dx,dx

int 10h

ret

vp_vesa2:

mov ax,4f05h

xor bx,bx

mov dx,vga_win1

int 10h

mov ax,4f05h

mov bx,0001h

mov dx,vga_win2

int 10h

ret

other_vga1:

cmp vga_type,3

jnz other_vga2

mov dx,3cdh

cmp ah,1

jz vp_tseng2

cmp ah,2

jz vp_tseng1

in al,dx

mov vga_win3,al

vp_tseng1:

xor al,al

out dx,al

ret

vp_tseng2:

mov al,vga_win3

out dx,al

vp_ret:

ret

other_vga2:

cmp vga_type,2

jnz vp_ret

mov al,0eh

mov dx,03c4h

cmp ah,1

jz vp_tvga2

out dx,al

inc dx

in al,dx

cmp ah,2

jz vp_tvga1

mov vga_win3,al

xor al,al

out dx,al

ret

vp_tvga1:

mov al,2

out dx,al

ret

vp_tvga2:

mov ah,vga_win3

out dx,ax

retVGA_PAGE ENDPVGA_BASE PROC mov dx,3c4h ;这一段是照抄的,找不到资料

mov ax,402h

out dx,ax

mov ax,704h

out dx,ax mov dx,3ceh

mov ax,0ff08h

out dx,ax

mov ax,0c06h

out dx,ax

mov ax,204h

out dx,ax

mov ax,5

out dx,ax

retVGA_BASE ENDP

;====================================================

;本子程序为恢复原来的显示内容

;在自己的程序执行完后使用RESTORE_SCR PROC push cs

pop ds mov al,video_mode ;根据不同的原显示模式不同处理

cmp al,3

jz rs_mode3

cmp al,7

jz rs_mode7 push 0b800h ;以下为图形方式恢复显示内容

pop es

push cs

pop ds

mov si,offset ram_buffer

xor di,di

mov cx,1000h

cld

rep movsb ;恢复显示 RAM

mov ah,2

call vga_page

call vga_base

call restore_vram xor ah,ah ;恢复到原来的显示模式

mov al,video_mode

or al,80h

int 10h mov ah,1

call vga_base

jmp short rs_mode31

rs_mode3:

call restore_vram

rs_mode31:

push cs

pop es

push cs

pop ds mov ax,1c02h ;恢复视频状态

mov bx,offset video_buffer

mov cx,7

int 10h test flag,10000000b

jz rs_no_mouse mov ax,17h ;恢复鼠标状态

mov dx,offset mouse_buffer

int 33h

rs_no_mouse:

ret

rs_mode7:

mov ax,7 ;显示模式 7 恢复

int 10h

push 0b000h

pop es

call restore_vram1

jmp short rs_mode31RESTORE_SCR ENDP

(出处:赢政天下整理收藏)

相关文章:

相关软件:

→ 特别推荐

→ 热点TOP10

我为人人《《==》》人人为我

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史