1 /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
2 /*                                                                 */
3 /* This library is free software; you can redistribute it and/or   */
4 /* modify it without any restrictions. This library is distributed */
5 /* in the hope that it will be useful, but without any warranty.   */
6 
7 /* Multi-chipset support Copyright 1993 Harm Hanemaayer */
8 /* partially copyrighted (C) 1993 by Hartmut Schirmer */
9 
10 /* Converted to especially ugly code and seriously hacked for Mach32: */
11 /* M. Weller in 1994                                                  */
12 #include <stdlib.h>
13 
14 #include "vga.h"
15 #include "vgabg.h"
16 #include "libvga.h"
17 #include "driver.h"
18 
19 static int current_index = -1;
20 static int setget = -1;		/* flag var to indicate last lut operation */
21 
22 /*
23  * In grayscale mode, we convert RGB colors to a Y component on the
24  * green-channel (the Y component is used in grayscale TV sets for the
25  * same purpose and corresponds to the "brightness" of the color as
26  * perceived by the human eye.  In order to be able to return to the
27  * user the original green-component, we save a backup copy of the
28  * green channel in __svgalib_green_backup:
29  */
30 int __svgalib_green_backup[256];
31 
32 
set_lut(int index,int red,int green,int blue)33 static int set_lut(int index, int red, int green, int blue)
34 {
35     if (__svgalib_novga) return 1;
36 
37     if (infotable[CM].colors>256) return 1;
38     /* setting palette when in high color mode could be useful, but it is
39     not a good idea at the moment */
40 
41     /* prevents lockups */
42     if ((__svgalib_chipset == MACH64)) {
43         outb(0x02ec+0x5c00,index);
44         outb(0x02ec+0x5c01,red);
45         outb(0x02ec+0x5c01,green);
46         outb(0x02ec+0x5c01,blue);
47         return 0;
48     }
49 
50     if ((index != current_index) || (setget != 1)) {
51 	/* select palette register */
52 	port_out(index, PEL_IW);
53 	current_index = index + 1;
54 	setget = 1;
55     } else
56 	current_index++;
57     /* write RGB components */
58     __svgalib_delay();
59     port_out(red, PEL_D);
60     __svgalib_delay();
61     port_out(green, PEL_D);
62     if (SCREENON) {		/* writing the `blue' register will   */
63 	while (!(inb(0x3da) & 1));	/* load the dac. Waiting for vertical */
64 	while (inb(0x3da) & 1);	/* or horizontal retrace will load    */
65     } else			/* the dac without disturbances       */
66 	__svgalib_delay();
67     port_out(blue, PEL_D);
68     return 0;
69 }
70 
71 
get_lut(int index,int * red,int * green,int * blue)72 static int get_lut(int index, int *red, int *green, int *blue)
73 {
74     if (__svgalib_novga) return 0;
75 
76     /* prevents lockups on mach64 */
77     if ((__svgalib_chipset == MACH64)) {
78         outb(0x02ec+0x5c00,index);
79         *red=inb(0x02ec+0x5c01);
80         *green=inb(0x02ec+0x5c01);
81         *blue=inb(0x02ec+0x5c01);
82         return 0;
83     }
84 
85     if ((index != current_index) || (setget != 0)) {
86 	/* select palette register */
87 	port_out(index, PEL_IR);
88 	current_index = index + 1;
89 	setget = 0;
90     } else
91 	current_index++;
92     /* read RGB components */
93     __svgalib_delay();
94     *red = (int) port_in(PEL_D);
95     __svgalib_delay();
96     *green = (int) port_in(PEL_D);
97     __svgalib_delay();
98     *blue = (int) port_in(PEL_D);
99 
100     return 0;
101 }
102 
103 #ifdef BACKGROUND
104 
vga_setpalette_bg(int index,int red,int green,int blue)105 static void vga_setpalette_bg(int index, int red, int green, int blue)
106 
107 {
108  unsigned char *tmp;
109  /* asume max 256 palette places. */
110  if (index<256)
111      {
112       tmp=__svgalib_give_graph_red();
113       tmp[index]=red;
114       tmp=__svgalib_give_graph_blue();
115       tmp[index]=blue;
116       tmp=__svgalib_give_graph_green();
117       tmp[index]=green;
118      }
119  return;
120 }
121 
122 #endif
123 
124 
vga_setpalette(int index,int red,int green,int blue)125 int vga_setpalette(int index, int red, int green, int blue)
126 {
127 #ifdef BACKGROUND
128  int tmp;
129 
130  __svgalib_dont_switch_vt_yet();
131 #endif
132     if (__svgalib_grayscale) {
133 	if ((unsigned) index >= sizeof(__svgalib_green_backup) / sizeof(__svgalib_green_backup[0])) {
134 	    printf("vga_setpalette: color index %d out of range\n", index);
135 	}
136 	__svgalib_green_backup[index] = green;
137 
138 	green = 0.299 * red + 0.587 * green + 0.114 * blue;
139 	if (green < 0)
140 	    green = 0;
141 	if (green > 255)
142 	    green = 255;
143     }
144 
145 #ifdef BACKGROUND
146     if (!vga_oktowrite()) {
147 	vga_setpalette_bg(index, red, green, blue);
148 	__svgalib_is_vt_switching_needed();
149 	return(0);
150     }
151     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->setpalette) {
152         tmp =__svgalib_driverspecs->emul->setpalette(index, red, green, blue);
153     } else {
154 	tmp = set_lut(index, red, green, blue);
155     }
156     __svgalib_is_vt_switching_needed();
157     return(tmp);
158 #else
159     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->setpalette) {
160         return __svgalib_driverspecs->emul->setpalette(index, red, green, blue);
161     } else {
162 	return set_lut(index, red, green, blue);
163     }
164 #endif
165 }
166 
167 #ifdef BACKGROUND
168 
vga_getpalette_bg(int index,int * red,int * green,int * blue)169 static void vga_getpalette_bg(int index, int *red, int *green, int *blue)
170 {
171  unsigned char *tmp;
172  /* asume max 256 palette places. */
173  if (index<256)
174      {
175       tmp=__svgalib_give_graph_red();
176       *red=tmp[index];
177       tmp=__svgalib_give_graph_blue();
178       *blue=tmp[index];
179       tmp=__svgalib_give_graph_green();
180       *green=tmp[index];
181      }
182  return;
183 }
184 
185 #endif
186 
vga_getpalette(int index,int * red,int * green,int * blue)187 int vga_getpalette(int index, int *red, int *green, int *blue)
188 {
189 #ifdef BACKGROUND
190  __svgalib_dont_switch_vt_yet();
191 #endif
192 #ifndef BACKGROUND
193     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->getpalette)
194         __svgalib_driverspecs->emul->getpalette(index, red, green, blue);
195     else get_lut(index, red, green, blue);
196 #endif
197 #ifdef BACKGROUND
198  if (!vga_oktowrite())
199      {
200       vga_getpalette_bg(index, red, green, blue);
201      }
202    else {
203     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->getpalette)
204         __svgalib_driverspecs->emul->getpalette(index, red, green, blue);
205     else get_lut(index, red, green, blue);
206    }
207 #endif
208     if (__svgalib_grayscale) {
209 	if ((unsigned) index >= sizeof(__svgalib_green_backup) / sizeof(__svgalib_green_backup[0])) {
210 	    printf("vga_getpalette: color index %d out of range\n", index);
211 	}
212 	*green = __svgalib_green_backup[index];
213     }
214 #ifdef BACKGROUND
215  __svgalib_is_vt_switching_needed();
216 #endif
217     return 0;
218 }
219 
220 
vga_setpalvec(int start,int num,int * pal)221 int vga_setpalvec(int start, int num, int *pal)
222 {
223     int i;
224 
225     for (i = start; i < start + num; ++i) {
226 	vga_setpalette(i, pal[0], pal[1], pal[2]);
227 	pal += 3;
228     }
229     return num;
230 }
231 
232 
vga_getpalvec(int start,int num,int * pal)233 int vga_getpalvec(int start, int num, int *pal)
234 {
235     int i;
236 
237     for (i = start; i < start + num; ++i) {
238 	vga_getpalette(i, pal + 0, pal + 1, pal + 2);
239 	pal += 3;
240     }
241     return num;
242 }
243