]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/MAI/bios_emulator/scitech/src/pm/common/vgastate.c
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / bios_emulator / scitech / src / pm / common / vgastate.c
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 /****************************************************************************
86 REMARKS:
87 Returns the size of the VGA state buffer.
88 ****************************************************************************/
89 int PMAPI PM_getVGAStateSize(void)
90 {
91     return CRT_C + ATT_C + GRA_C + SEQ_C + MIS_C + PAL_C + FONT_C;
92 }
93
94 /****************************************************************************
95 REMARKS:
96 Delay for a short period of time.
97 ****************************************************************************/
98 static 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++)
107         PM_outpb(0x80, 0);
108 }
109
110 /****************************************************************************
111 PARAMETERS:
112 port    - I/O port to read value from
113 index   - Port index to read
114
115 RETURNS:
116 Byte read from 'port' register 'index'.
117 ****************************************************************************/
118 static 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 /****************************************************************************
127 PARAMETERS:
128 port    - I/O port to write to
129 index   - Port index to write
130 value   - Byte to write to port
131
132 REMARKS:
133 Writes a byte value to the 'port' register 'index'.
134 ****************************************************************************/
135 static 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 /****************************************************************************
145 REMARKS:
146 Save the color palette values
147 ****************************************************************************/
148 static void vga_savepalette(
149     uchar *pal)
150 {
151     int i;
152
153     _port_out(0, PEL_IR);
154     for (i = 0; i < 768; i++) {
155         vga_delay();
156         *pal++ = _port_in(PEL_D);
157         }
158 }
159
160 /****************************************************************************
161 REMARKS:
162 Restore the color palette values
163 ****************************************************************************/
164 static 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++) {
172         vga_delay();
173         _port_out(*pal++, PEL_D);
174         }
175 }
176
177 /****************************************************************************
178 REMARKS:
179 Read the font data from the VGA character generator RAM
180 ****************************************************************************/
181 static 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 /****************************************************************************
217 REMARKS:
218 Downloads the font data to the VGA character generator RAM
219 ****************************************************************************/
220 static 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 /****************************************************************************
239 REMARKS:
240 Save the state of all VGA compatible registers
241 ****************************************************************************/
242 void 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++) {
250         _port_out(i, CRT_I);
251         regs[CRT + i] = _port_in(CRT_D);
252         }
253     for (i = 0; i < ATT_C; i++) {
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         }
261     for (i = 0; i < GRA_C; i++) {
262         _port_out(i, GRA_I);
263         regs[GRA + i] = _port_in(GRA_D);
264         }
265     for (i = 0; i < SEQ_C; i++) {
266         _port_out(i, SEQ_I);
267         regs[SEQ + i] = _port_in(SEQ_D);
268         }
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 /****************************************************************************
282 REMARKS:
283 Retore the state of all VGA compatible registers
284 ****************************************************************************/
285 void 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++)
305         vga_delay();
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++) {
315         _port_out(i, SEQ_I);
316         _port_out(regs[SEQ + i], SEQ_D);
317         }
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++) {
327         _port_out(i, CRT_I);
328         _port_out(regs[CRT + i], CRT_D);
329         }
330     for (i = 0; i < GRA_C; i++) {
331         _port_out(i, GRA_I);
332         _port_out(regs[GRA + i], GRA_D);
333         }
334     for (i = 0; i < ATT_C; i++) {
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         }
342
343     /* Ensure the VGA screen is turned on */
344     PM_vgaUnblankDisplay();
345 }
346
347 /****************************************************************************
348 REMARKS:
349 Disables the VGA display for screen output making it blank.
350 ****************************************************************************/
351 void 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 /****************************************************************************
364 REMARKS:
365 Enables the VGA display for screen output.
366 ****************************************************************************/
367 void 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 }