]> git.ipfire.org Git - u-boot.git/blame - board/MAI/bios_emulator/scitech/src/pm/common/vgastate.c
* Code cleanup:
[u-boot.git] / board / MAI / bios_emulator / scitech / src / pm / common / vgastate.c
CommitLineData
c7de829c
WD
1/****************************************************************************
2*
3* SciTech OS Portability Manager Library
4*
5* ========================================================================
6*
7* The contents of this file are subject to the SciTech MGL Public
8* License Version 1.0 (the "License"); you may not use this file
9* except in compliance with the License. You may obtain a copy of
10* the License at http://www.scitechsoft.com/mgl-license.txt
11*
12* Software distributed under the License is distributed on an
13* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14* implied. See the License for the specific language governing
15* rights and limitations under the License.
16*
17* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18*
19* The Initial Developer of the Original Code is SciTech Software, Inc.
20* All Rights Reserved.
21*
22* ========================================================================
23*
24* Portions copyright (C) Josh Vanderhoof
25*
26* Language: ANSI C
27* Environment: Any
28*
29* Description: Functions to save and restore the VGA hardware state.
30*
31****************************************************************************/
32
33#include "pmapi.h"
34#if defined(__WIN32_VXD__) || defined(__NT_DRIVER__)
35#include "sdd/sddhelp.h"
36#else
37#include <string.h>
38#endif
39
40/*--------------------------- Global variables ----------------------------*/
41
42/* VGA index register ports */
43#define CRT_I 0x3D4 /* CRT Controller Index */
44#define ATT_IW 0x3C0 /* Attribute Controller Index & Data */
45#define GRA_I 0x3CE /* Graphics Controller Index */
46#define SEQ_I 0x3C4 /* Sequencer Index */
47
48/* VGA data register ports */
49#define CRT_D 0x3D5 /* CRT Controller Data Register */
50#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */
51#define GRA_D 0x3CF /* Graphics Controller Data Register */
52#define SEQ_D 0x3C5 /* Sequencer Data Register */
53#define MIS_R 0x3CC /* Misc Output Read Register */
54#define MIS_W 0x3C2 /* Misc Output Write Register */
55#define IS1_R 0x3DA /* Input Status Register 1 */
56#define PEL_IW 0x3C8 /* PEL Write Index */
57#define PEL_IR 0x3C7 /* PEL Read Index */
58#define PEL_D 0x3C9 /* PEL Data Register */
59
60/* standard VGA indexes max counts */
61#define CRT_C 24 /* 24 CRT Controller Registers */
62#define ATT_C 21 /* 21 Attribute Controller Registers */
63#define GRA_C 9 /* 9 Graphics Controller Registers */
64#define SEQ_C 5 /* 5 Sequencer Registers */
65#define MIS_C 1 /* 1 Misc Output Register */
66#define PAL_C 768 /* 768 Palette Registers */
67#define FONT_C 8192 /* Total size of character generator RAM */
68
69/* VGA registers saving indexes */
70#define CRT 0 /* CRT Controller Registers start */
71#define ATT (CRT+CRT_C) /* Attribute Controller Registers start */
72#define GRA (ATT+ATT_C) /* Graphics Controller Registers start */
73#define SEQ (GRA+GRA_C) /* Sequencer Registers */
74#define MIS (SEQ+SEQ_C) /* General Registers */
75#define PAL (MIS+MIS_C) /* VGA Palette Registers */
76#define FONT (PAL+PAL_C) /* VGA font data */
77
78/* Macros for port I/O with arguments reversed */
79
80#define _port_out(v,p) PM_outpb(p,(uchar)(v))
81#define _port_in(p) PM_inpb(p)
82
83/*----------------------------- Implementation ----------------------------*/
84
85/****************************************************************************
86REMARKS:
87Returns the size of the VGA state buffer.
88****************************************************************************/
89int PMAPI PM_getVGAStateSize(void)
90{
91 return CRT_C + ATT_C + GRA_C + SEQ_C + MIS_C + PAL_C + FONT_C;
92}
93
94/****************************************************************************
95REMARKS:
96Delay for a short period of time.
97****************************************************************************/
98static void vga_delay(void)
99{
100 int i;
101
102 /* For the loop here we program the POST register. The length of this
103 * delay is dependant only on ISA bus speed, but it is enough for
104 * what we need.
105 */
106 for (i = 0; i <= 10; i++)
8bde7f77 107 PM_outpb(0x80, 0);
c7de829c
WD
108}
109
110/****************************************************************************
111PARAMETERS:
112port - I/O port to read value from
113index - Port index to read
114
115RETURNS:
116Byte read from 'port' register 'index'.
117****************************************************************************/
118static ushort vga_rdinx(
119 ushort port,
120 ushort index)
121{
122 PM_outpb(port,(uchar)index);
123 return PM_inpb(port+1);
124}
125
126/****************************************************************************
127PARAMETERS:
128port - I/O port to write to
129index - Port index to write
130value - Byte to write to port
131
132REMARKS:
133Writes a byte value to the 'port' register 'index'.
134****************************************************************************/
135static void vga_wrinx(
136 ushort port,
137 ushort index,
138 ushort value)
139{
140 PM_outpb(port,(uchar)index);
141 PM_outpb(port+1,(uchar)value);
142}
143
144/****************************************************************************
145REMARKS:
146Save the color palette values
147****************************************************************************/
148static void vga_savepalette(
149 uchar *pal)
150{
151 int i;
152
153 _port_out(0, PEL_IR);
154 for (i = 0; i < 768; i++) {
8bde7f77
WD
155 vga_delay();
156 *pal++ = _port_in(PEL_D);
157 }
c7de829c
WD
158}
159
160/****************************************************************************
161REMARKS:
162Restore the color palette values
163****************************************************************************/
164static void vga_restorepalette(
165 const uchar *pal)
166{
167 int i;
168
169 /* restore saved palette */
170 _port_out(0, PEL_IW);
171 for (i = 0; i < 768; i++) {
8bde7f77
WD
172 vga_delay();
173 _port_out(*pal++, PEL_D);
174 }
c7de829c
WD
175}
176
177/****************************************************************************
178REMARKS:
179Read the font data from the VGA character generator RAM
180****************************************************************************/
181static void vga_saveFont(
182 uchar *data)
183{
184 uchar *A0000Ptr = PM_getA0000Pointer();
185 uchar save[7];
186
187 /* Enable access to character generator RAM */
188 save[0] = (uchar)vga_rdinx(SEQ_I,0x00);
189 save[1] = (uchar)vga_rdinx(SEQ_I,0x02);
190 save[2] = (uchar)vga_rdinx(SEQ_I,0x04);
191 save[3] = (uchar)vga_rdinx(SEQ_I,0x00);
192 save[4] = (uchar)vga_rdinx(GRA_I,0x04);
193 save[5] = (uchar)vga_rdinx(GRA_I,0x05);
194 save[6] = (uchar)vga_rdinx(GRA_I,0x06);
195 vga_wrinx(SEQ_I,0x00,0x01);
196 vga_wrinx(SEQ_I,0x02,0x04);
197 vga_wrinx(SEQ_I,0x04,0x07);
198 vga_wrinx(SEQ_I,0x00,0x03);
199 vga_wrinx(GRA_I,0x04,0x02);
200 vga_wrinx(GRA_I,0x05,0x00);
201 vga_wrinx(GRA_I,0x06,0x00);
202
203 /* Copy character generator RAM */
204 memcpy(data,A0000Ptr,FONT_C);
205
206 /* Restore VGA state */
207 vga_wrinx(SEQ_I,0x00,save[0]);
208 vga_wrinx(SEQ_I,0x02,save[1]);
209 vga_wrinx(SEQ_I,0x04,save[2]);
210 vga_wrinx(SEQ_I,0x00,save[3]);
211 vga_wrinx(GRA_I,0x04,save[4]);
212 vga_wrinx(GRA_I,0x05,save[5]);
213 vga_wrinx(GRA_I,0x06,save[6]);
214}
215
216/****************************************************************************
217REMARKS:
218Downloads the font data to the VGA character generator RAM
219****************************************************************************/
220static void vga_restoreFont(
221 const uchar *data)
222{
223 uchar *A0000Ptr = PM_getA0000Pointer();
224
225 /* Enable access to character generator RAM */
226 vga_wrinx(SEQ_I,0x00,0x01);
227 vga_wrinx(SEQ_I,0x02,0x04);
228 vga_wrinx(SEQ_I,0x04,0x07);
229 vga_wrinx(SEQ_I,0x00,0x03);
230 vga_wrinx(GRA_I,0x04,0x02);
231 vga_wrinx(GRA_I,0x05,0x00);
232 vga_wrinx(GRA_I,0x06,0x00);
233
234 /* Copy font back to character generator RAM */
235 memcpy(A0000Ptr,data,FONT_C);
236}
237
238/****************************************************************************
239REMARKS:
240Save the state of all VGA compatible registers
241****************************************************************************/
242void PMAPI PM_saveVGAState(
243 void *stateBuf)
244{
245 uchar *regs = stateBuf;
246 int i;
247
248 /* Save state of VGA registers */
249 for (i = 0; i < CRT_C; i++) {
8bde7f77
WD
250 _port_out(i, CRT_I);
251 regs[CRT + i] = _port_in(CRT_D);
252 }
c7de829c 253 for (i = 0; i < ATT_C; i++) {
8bde7f77
WD
254 _port_in(IS1_R);
255 vga_delay();
256 _port_out(i, ATT_IW);
257 vga_delay();
258 regs[ATT + i] = _port_in(ATT_R);
259 vga_delay();
260 }
c7de829c 261 for (i = 0; i < GRA_C; i++) {
8bde7f77
WD
262 _port_out(i, GRA_I);
263 regs[GRA + i] = _port_in(GRA_D);
264 }
c7de829c 265 for (i = 0; i < SEQ_C; i++) {
8bde7f77
WD
266 _port_out(i, SEQ_I);
267 regs[SEQ + i] = _port_in(SEQ_D);
268 }
c7de829c
WD
269 regs[MIS] = _port_in(MIS_R);
270
271 /* Save the VGA palette values */
272 vga_savepalette(&regs[PAL]);
273
274 /* Save the VGA character generator RAM */
275 vga_saveFont(&regs[FONT]);
276
277 /* Turn the VGA display back on */
278 PM_vgaUnblankDisplay();
279}
280
281/****************************************************************************
282REMARKS:
283Retore the state of all VGA compatible registers
284****************************************************************************/
285void PMAPI PM_restoreVGAState(
286 const void *stateBuf)
287{
288 const uchar *regs = stateBuf;
289 int i;
290
291 /* Blank the display before we start the restore */
292 PM_vgaBlankDisplay();
293
294 /* Restore the VGA character generator RAM */
295 vga_restoreFont(&regs[FONT]);
296
297 /* Restore the VGA palette values */
298 vga_restorepalette(&regs[PAL]);
299
300 /* Restore the state of the VGA compatible registers */
301 _port_out(regs[MIS], MIS_W);
302
303 /* Delay to allow clock change to settle */
304 for (i = 0; i < 10; i++)
8bde7f77 305 vga_delay();
c7de829c
WD
306
307 /* Synchronous reset on */
308 _port_out(0x00,SEQ_I);
309 _port_out(0x01,SEQ_D);
310
311 /* Write seqeuencer registers */
312 _port_out(1, SEQ_I);
313 _port_out(regs[SEQ + 1] | 0x20, SEQ_D);
314 for (i = 2; i < SEQ_C; i++) {
8bde7f77
WD
315 _port_out(i, SEQ_I);
316 _port_out(regs[SEQ + i], SEQ_D);
317 }
c7de829c
WD
318
319 /* Synchronous reset off */
320 _port_out(0x00,SEQ_I);
321 _port_out(0x03,SEQ_D);
322
323 /* Deprotect CRT registers 0-7 and write CRTC */
324 _port_out(0x11, CRT_I);
325 _port_out(_port_in(CRT_D) & 0x7F, CRT_D);
326 for (i = 0; i < CRT_C; i++) {
8bde7f77
WD
327 _port_out(i, CRT_I);
328 _port_out(regs[CRT + i], CRT_D);
329 }
c7de829c 330 for (i = 0; i < GRA_C; i++) {
8bde7f77
WD
331 _port_out(i, GRA_I);
332 _port_out(regs[GRA + i], GRA_D);
333 }
c7de829c 334 for (i = 0; i < ATT_C; i++) {
8bde7f77
WD
335 _port_in(IS1_R); /* reset flip-flop */
336 vga_delay();
337 _port_out(i, ATT_IW);
338 vga_delay();
339 _port_out(regs[ATT + i], ATT_IW);
340 vga_delay();
341 }
c7de829c
WD
342
343 /* Ensure the VGA screen is turned on */
344 PM_vgaUnblankDisplay();
345}
346
347/****************************************************************************
348REMARKS:
349Disables the VGA display for screen output making it blank.
350****************************************************************************/
351void PMAPI PM_vgaBlankDisplay(void)
352{
353 /* Turn screen off */
354 _port_out(0x01, SEQ_I);
355 _port_out(_port_in(SEQ_D) | 0x20, SEQ_D);
356
357 /* Disable video output */
358 _port_in(IS1_R);
359 vga_delay();
360 _port_out(0x00, ATT_IW);
361}
362
363/****************************************************************************
364REMARKS:
365Enables the VGA display for screen output.
366****************************************************************************/
367void PMAPI PM_vgaUnblankDisplay(void)
368{
369 /* Turn screen back on */
370 _port_out(0x01, SEQ_I);
371 _port_out(_port_in(SEQ_D) & 0xDF, SEQ_D);
372
373 /* Enable video output */
374 _port_in(IS1_R);
375 vga_delay();
376 _port_out(0x20, ATT_IW);
377}