📄 vgastate.c
字号:
/****************************************************************************** SciTech OS Portability Manager Library** ========================================================================** The contents of this file are subject to the SciTech MGL Public* License Version 1.0 (the "License"); you may not use this file* except in compliance with the License. You may obtain a copy of* the License at http://www.scitechsoft.com/mgl-license.txt** Software distributed under the License is distributed on an* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or* implied. See the License for the specific language governing* rights and limitations under the License.** The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.** The Initial Developer of the Original Code is SciTech Software, Inc.* All Rights Reserved.** ========================================================================** Portions copyright (C) Josh Vanderhoof** Language: ANSI C* Environment: Any** Description: Functions to save and restore the VGA hardware state.*****************************************************************************/#include "pmapi.h"#if defined(__WIN32_VXD__) || defined(__NT_DRIVER__)#include "sdd/sddhelp.h"#else#include <string.h>#endif/*--------------------------- Global variables ----------------------------*//* VGA index register ports */#define CRT_I 0x3D4 /* CRT Controller Index */#define ATT_IW 0x3C0 /* Attribute Controller Index & Data */#define GRA_I 0x3CE /* Graphics Controller Index */#define SEQ_I 0x3C4 /* Sequencer Index *//* VGA data register ports */#define CRT_D 0x3D5 /* CRT Controller Data Register */#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */#define GRA_D 0x3CF /* Graphics Controller Data Register */#define SEQ_D 0x3C5 /* Sequencer Data Register */#define MIS_R 0x3CC /* Misc Output Read Register */#define MIS_W 0x3C2 /* Misc Output Write Register */#define IS1_R 0x3DA /* Input Status Register 1 */#define PEL_IW 0x3C8 /* PEL Write Index */#define PEL_IR 0x3C7 /* PEL Read Index */#define PEL_D 0x3C9 /* PEL Data Register *//* standard VGA indexes max counts */#define CRT_C 24 /* 24 CRT Controller Registers */#define ATT_C 21 /* 21 Attribute Controller Registers */#define GRA_C 9 /* 9 Graphics Controller Registers */#define SEQ_C 5 /* 5 Sequencer Registers */#define MIS_C 1 /* 1 Misc Output Register */#define PAL_C 768 /* 768 Palette Registers */#define FONT_C 8192 /* Total size of character generator RAM *//* VGA registers saving indexes */#define CRT 0 /* CRT Controller Registers start */#define ATT (CRT+CRT_C) /* Attribute Controller Registers start */#define GRA (ATT+ATT_C) /* Graphics Controller Registers start */#define SEQ (GRA+GRA_C) /* Sequencer Registers */#define MIS (SEQ+SEQ_C) /* General Registers */#define PAL (MIS+MIS_C) /* VGA Palette Registers */#define FONT (PAL+PAL_C) /* VGA font data *//* Macros for port I/O with arguments reversed */#define _port_out(v,p) PM_outpb(p,(uchar)(v))#define _port_in(p) PM_inpb(p)/*----------------------------- Implementation ----------------------------*//****************************************************************************REMARKS:Returns the size of the VGA state buffer.****************************************************************************/int PMAPI PM_getVGAStateSize(void){ return CRT_C + ATT_C + GRA_C + SEQ_C + MIS_C + PAL_C + FONT_C;}/****************************************************************************REMARKS:Delay for a short period of time.****************************************************************************/static void vga_delay(void){ int i; /* For the loop here we program the POST register. The length of this * delay is dependant only on ISA bus speed, but it is enough for * what we need. */ for (i = 0; i <= 10; i++) PM_outpb(0x80, 0);}/****************************************************************************PARAMETERS:port - I/O port to read value fromindex - Port index to readRETURNS:Byte read from 'port' register 'index'.****************************************************************************/static ushort vga_rdinx( ushort port, ushort index){ PM_outpb(port,(uchar)index); return PM_inpb(port+1);}/****************************************************************************PARAMETERS:port - I/O port to write toindex - Port index to writevalue - Byte to write to portREMARKS:Writes a byte value to the 'port' register 'index'.****************************************************************************/static void vga_wrinx( ushort port, ushort index, ushort value){ PM_outpb(port,(uchar)index); PM_outpb(port+1,(uchar)value);}/****************************************************************************REMARKS:Save the color palette values****************************************************************************/static void vga_savepalette( uchar *pal){ int i; _port_out(0, PEL_IR); for (i = 0; i < 768; i++) { vga_delay(); *pal++ = _port_in(PEL_D); }}/****************************************************************************REMARKS:Restore the color palette values****************************************************************************/static void vga_restorepalette( const uchar *pal){ int i; /* restore saved palette */ _port_out(0, PEL_IW); for (i = 0; i < 768; i++) { vga_delay(); _port_out(*pal++, PEL_D); }}/****************************************************************************REMARKS:Read the font data from the VGA character generator RAM****************************************************************************/static void vga_saveFont( uchar *data){ uchar *A0000Ptr = PM_getA0000Pointer(); uchar save[7]; /* Enable access to character generator RAM */ save[0] = (uchar)vga_rdinx(SEQ_I,0x00); save[1] = (uchar)vga_rdinx(SEQ_I,0x02); save[2] = (uchar)vga_rdinx(SEQ_I,0x04); save[3] = (uchar)vga_rdinx(SEQ_I,0x00); save[4] = (uchar)vga_rdinx(GRA_I,0x04); save[5] = (uchar)vga_rdinx(GRA_I,0x05); save[6] = (uchar)vga_rdinx(GRA_I,0x06); vga_wrinx(SEQ_I,0x00,0x01); vga_wrinx(SEQ_I,0x02,0x04); vga_wrinx(SEQ_I,0x04,0x07); vga_wrinx(SEQ_I,0x00,0x03); vga_wrinx(GRA_I,0x04,0x02); vga_wrinx(GRA_I,0x05,0x00); vga_wrinx(GRA_I,0x06,0x00); /* Copy character generator RAM */ memcpy(data,A0000Ptr,FONT_C); /* Restore VGA state */ vga_wrinx(SEQ_I,0x00,save[0]); vga_wrinx(SEQ_I,0x02,save[1]); vga_wrinx(SEQ_I,0x04,save[2]); vga_wrinx(SEQ_I,0x00,save[3]); vga_wrinx(GRA_I,0x04,save[4]); vga_wrinx(GRA_I,0x05,save[5]); vga_wrinx(GRA_I,0x06,save[6]);}/****************************************************************************REMARKS:Downloads the font data to the VGA character generator RAM****************************************************************************/static void vga_restoreFont( const uchar *data){ uchar *A0000Ptr = PM_getA0000Pointer(); /* Enable access to character generator RAM */ vga_wrinx(SEQ_I,0x00,0x01); vga_wrinx(SEQ_I,0x02,0x04); vga_wrinx(SEQ_I,0x04,0x07); vga_wrinx(SEQ_I,0x00,0x03); vga_wrinx(GRA_I,0x04,0x02); vga_wrinx(GRA_I,0x05,0x00); vga_wrinx(GRA_I,0x06,0x00); /* Copy font back to character generator RAM */ memcpy(A0000Ptr,data,FONT_C);}/****************************************************************************REMARKS:Save the state of all VGA compatible registers****************************************************************************/void PMAPI PM_saveVGAState( void *stateBuf){ uchar *regs = stateBuf; int i; /* Save state of VGA registers */ for (i = 0; i < CRT_C; i++) { _port_out(i, CRT_I); regs[CRT + i] = _port_in(CRT_D); } for (i = 0; i < ATT_C; i++) { _port_in(IS1_R); vga_delay(); _port_out(i, ATT_IW); vga_delay(); regs[ATT + i] = _port_in(ATT_R); vga_delay(); } for (i = 0; i < GRA_C; i++) { _port_out(i, GRA_I); regs[GRA + i] = _port_in(GRA_D); } for (i = 0; i < SEQ_C; i++) { _port_out(i, SEQ_I); regs[SEQ + i] = _port_in(SEQ_D); } regs[MIS] = _port_in(MIS_R); /* Save the VGA palette values */ vga_savepalette(®s[PAL]); /* Save the VGA character generator RAM */ vga_saveFont(®s[FONT]); /* Turn the VGA display back on */ PM_vgaUnblankDisplay();}/****************************************************************************REMARKS:Retore the state of all VGA compatible registers****************************************************************************/void PMAPI PM_restoreVGAState( const void *stateBuf){ const uchar *regs = stateBuf; int i; /* Blank the display before we start the restore */ PM_vgaBlankDisplay(); /* Restore the VGA character generator RAM */ vga_restoreFont(®s[FONT]); /* Restore the VGA palette values */ vga_restorepalette(®s[PAL]); /* Restore the state of the VGA compatible registers */ _port_out(regs[MIS], MIS_W); /* Delay to allow clock change to settle */ for (i = 0; i < 10; i++) vga_delay(); /* Synchronous reset on */ _port_out(0x00,SEQ_I); _port_out(0x01,SEQ_D); /* Write seqeuencer registers */ _port_out(1, SEQ_I); _port_out(regs[SEQ + 1] | 0x20, SEQ_D); for (i = 2; i < SEQ_C; i++) { _port_out(i, SEQ_I); _port_out(regs[SEQ + i], SEQ_D); } /* Synchronous reset off */ _port_out(0x00,SEQ_I); _port_out(0x03,SEQ_D); /* Deprotect CRT registers 0-7 and write CRTC */ _port_out(0x11, CRT_I); _port_out(_port_in(CRT_D) & 0x7F, CRT_D); for (i = 0; i < CRT_C; i++) { _port_out(i, CRT_I); _port_out(regs[CRT + i], CRT_D); } for (i = 0; i < GRA_C; i++) { _port_out(i, GRA_I); _port_out(regs[GRA + i], GRA_D); } for (i = 0; i < ATT_C; i++) { _port_in(IS1_R); /* reset flip-flop */ vga_delay(); _port_out(i, ATT_IW); vga_delay(); _port_out(regs[ATT + i], ATT_IW); vga_delay(); } /* Ensure the VGA screen is turned on */ PM_vgaUnblankDisplay();}/****************************************************************************REMARKS:Disables the VGA display for screen output making it blank.****************************************************************************/void PMAPI PM_vgaBlankDisplay(void){ /* Turn screen off */ _port_out(0x01, SEQ_I); _port_out(_port_in(SEQ_D) | 0x20, SEQ_D); /* Disable video output */ _port_in(IS1_R); vga_delay(); _port_out(0x00, ATT_IW);}/****************************************************************************REMARKS:Enables the VGA display for screen output.****************************************************************************/void PMAPI PM_vgaUnblankDisplay(void){ /* Turn screen back on */ _port_out(0x01, SEQ_I); _port_out(_port_in(SEQ_D) & 0xDF, SEQ_D); /* Enable video output */ _port_in(IS1_R); vga_delay(); _port_out(0x20, ATT_IW);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -