<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      圖形顯示方式屏幕的保存與恢復

      [摘要]在程序中常常要暫時的保存圖形顯示方式屏幕上的內容,然后把自己的信息輸出到屏幕上,結束后再恢復原來的屏幕內容,特別在內存駐留程序彈出一個窗口時更要用到,但是圖形方式下顯示緩沖區的容量巨大,在常用的 80 x 25 文本方式下,顯示緩沖區僅大小僅為 80 x 25 x 2 = 4000 字節,而在模式...
      在程序中常常要暫時的保存圖形顯示方式屏幕上的內容,然后把自己的信息輸出到屏幕上,結束后再恢復原來的屏幕內容,特別在內存駐留程序彈出一個窗口時更要用到,但是圖形方式下顯示緩沖區的容量巨大,在常用的 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_ret
      SAVE_SCR ENDP
      SAVE_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 ENDP
      RESTORE_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 ENDP
      VGA_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
      ret
      VGA_PAGE ENDP
      VGA_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
      ret
      VGA_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_mode31
      RESTORE_SCR ENDP


      日韩精品一区二区三区高清