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
11 #include <stdlib.h> /* for NULL */
12 #include "vga.h"
13 #include "libvga.h"
14 #include "driver.h"
15
16 /* BIOS mode 0Dh - 320x200x16 */
17 static const unsigned char g320x200x16_regs[60] =
18 {
19 0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
20 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3,
21 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
22 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00,
23 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF,
24 0x03, 0x09, 0x0F, 0x00, 0x06,
25 0x63
26 };
27
28 /* BIOS mode 0Eh - 640x200x16 */
29 static const unsigned char g640x200x16_regs[60] =
30 {
31 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3,
33 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
34 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00,
35 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF,
36 0x03, 0x01, 0x0F, 0x00, 0x06,
37 0x63
38 };
39
40 /* BIOS mode 10h - 640x350x16 */
41 static const unsigned char g640x350x16_regs[60] =
42 {
43 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3,
45 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
46 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00,
47 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF,
48 0x03, 0x01, 0x0F, 0x00, 0x06,
49 0xA3
50 };
51
52 /* BIOS mode 12h - 640x480x16 */
53 static const unsigned char g640x480x16_regs[60] =
54 {
55 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
57 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
58 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00,
59 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF,
60 0x03, 0x01, 0x0F, 0x00, 0x06,
61 0xE3
62 };
63
64 /* BIOS mode 13h - 320x200x256 */
65 static const unsigned char g320x200x256_regs[60] =
66 {
67 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
69 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
70 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF,
72 0x03, 0x01, 0x0F, 0x00, 0x0E,
73 0x63
74 };
75
76 /* non-BIOS mode - 320x240x256 */
77 static const unsigned char g320x240x256_regs[60] =
78 {
79 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0D, 0x3E, 0x00, 0x41, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0xEA, 0xAC, 0xDF, 0x28, 0x00, 0xE7, 0x06, 0xE3,
81 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
82 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF,
84 0x03, 0x01, 0x0F, 0x00, 0x06,
85 0xE3
86 };
87
88 /* non-BIOS mode - 320x400x256 */
89 static const unsigned char g320x400x256_regs[60] =
90 {
91 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3,
93 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
94 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF,
96 0x03, 0x01, 0x0F, 0x00, 0x06,
97 0x63
98 };
99
100 /* non-BIOS mode - 360x480x256 */
101 static const unsigned char g360x480x256_regs[60] =
102 {
103 0x6B, 0x59, 0x5A, 0x8E, 0x5E, 0x8A, 0x0D, 0x3E, 0x00, 0x40, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0xEA, 0xAC, 0xDF, 0x2D, 0x00, 0xE7, 0x06, 0xE3,
105 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
106 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF,
108 0x03, 0x01, 0x0F, 0x00, 0x06,
109 0xE7
110 };
111
112 /* monochrome mode based on BIOS mode 12h - 640x480x2 */
113 #define g640x480x2_regs g640x480x16_regs
114
115 /* non BIOS mode - 720x348x2 based on mode 10h */
116 static const unsigned char g720x348x2_regs[60] =
117 {
118 0x6B, 0x59, 0x5A, 0x8E, 0x5E, 0x8A, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x2D, 0x0F, 0x63, 0xBA, 0xE3,
120 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
121 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00,
122 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF,
123 0x03, 0x01, 0x0F, 0x00, 0x06,
124 0xA7
125 };
126
127
128 /* Mode table */
129 static ModeTable vga_modes[] =
130 {
131 /* *INDENT-OFF* */
132 OneModeEntry(640x480x2),
133 OneModeEntry(720x348x2),
134 OneModeEntry(320x200x16),
135 OneModeEntry(640x200x16),
136 OneModeEntry(640x350x16),
137 OneModeEntry(640x480x16),
138 OneModeEntry(320x200x256),
139 OneModeEntry(320x240x256),
140 OneModeEntry(320x400x256),
141 OneModeEntry(360x480x256),
142 #ifdef G720x350x16
143 OneModeEntry(720x350x16),
144 #endif
145 END_OF_MODE_TABLE
146 /* *INDENT-ON* */
147 };
148
149
150 /* Fill in chipset-specific modeinfo */
151
getmodeinfo(int mode,vga_modeinfo * modeinfo)152 static void getmodeinfo(int mode, vga_modeinfo * modeinfo)
153 {
154 if (modeinfo->bytesperpixel == 1) { /* 320x200x256 linear mode */
155 modeinfo->maxpixels = 65536;
156 modeinfo->startaddressrange = 0xffff;
157 } else
158 switch (modeinfo->colors) {
159 case 16: /* 4-plane 16 color mode */
160 modeinfo->maxpixels = 65536 * 8;
161 modeinfo->startaddressrange = 0x7ffff;
162 break;
163 case 256: /* 4-plane 256 color mode */
164 modeinfo->maxpixels = 65536 * 4;
165 modeinfo->startaddressrange = 0x3ffff;
166 break;
167 }
168 modeinfo->maxlogicalwidth = 2040;
169 modeinfo->haveblit = 0;
170 modeinfo->flags &= ~(IS_INTERLACED | HAVE_RWPAGE);
171 }
172
nothing(void)173 static void nothing(void)
174 {
175 }
176
saveregs(unsigned char regs[])177 static int saveregs(unsigned char regs[])
178 {
179 return 0;
180 }
181
setregs(const unsigned char regs[],int mode)182 static void setregs(const unsigned char regs[], int mode)
183 {
184 }
185
186 /* Return nonzero if mode available */
187
modeavailable(int mode)188 static int modeavailable(int mode)
189 {
190 const unsigned char *regs;
191
192 regs = LOOKUPMODE(vga_modes, mode);
193 if (regs != NULL && regs != DISABLE_MODE)
194 return STDVGADRV;
195 return 0;
196 }
197
198
199 /* Set a mode */
200
201 static int lastmode;
202
setmode(int mode,int prv_mode)203 static int setmode(int mode, int prv_mode)
204 {
205 /* standard VGA driver: setmode */
206 const unsigned char *regs;
207
208 if (mode == TEXT)
209 return 0; /* Do nothing. */
210
211 regs = LOOKUPMODE(vga_modes, mode);
212 if (regs == NULL || regs == DISABLE_MODE)
213 return 1;
214 lastmode = mode;
215 __svgalib_setregs(regs);
216 return 0;
217 }
218
219 /* Set display start */
220
setdisplaystart(int address)221 static void setdisplaystart(int address)
222 {
223 vga_modeinfo *modeinfo;
224 modeinfo = vga_getmodeinfo(lastmode);
225 if (modeinfo->bytesperpixel == 0) /* not 320x200x256 linear */
226 switch (modeinfo->colors) {
227 case 16: /* planar 16-color mode */
228 inb(0x3da);
229 outb(ATT_IW, 0x13 + 0x20);
230 outb(ATT_IW, (inb(ATT_R) & 0xf0) | (address & 7));
231 /* write sa0-2 to bits 0-2 */
232 address >>= 3;
233 break;
234 case 256: /* planar 256-color mode */
235 inb(0x3da);
236 outb(ATT_IW, 0x13 + 0x20);
237 outb(ATT_IW, (inb(ATT_R) & 0xf0) | ((address & 3) << 1));
238 /* write sa0-1 to bits 1-2 */
239 address >>= 2;
240 break;
241 }
242 outw(CRT_IC, 0x0d + (address & 0x00ff) * 256); /* sa0-sa7 */
243 outw(CRT_IC, 0x0c + (address & 0xff00)); /* sa8-sa15 */
244 }
245
setlogicalwidth(int width)246 static void setlogicalwidth(int width)
247 {
248 outw(CRT_IC, 0x13 + (width >> 3) * 256); /* lw3-lw11 */
249 }
250
251 static int vgadrv_init(int, int, int);
252
vga_test(void)253 static int vga_test(void)
254 {
255 unsigned char save, back;
256
257 /* Check if a DAC is present */
258 save = inb(PEL_IW);
259 __svgalib_delay();
260 outb(PEL_IW, ~save);
261 __svgalib_delay();
262 back = inb(PEL_IW);
263 __svgalib_delay();
264 outb(PEL_IW, save);
265 save = ~save;
266 __svgalib_banked_mem_base=0xa0000;
267 __svgalib_banked_mem_size=0x10000;
268 if (back == save) {
269 vgadrv_init(0, 0, 0);
270 return 1;
271 }
272 return 0;
273 }
274
275
276 DriverSpecs __svgalib_vga_driverspecs =
277 { /* standard VGA */
278 saveregs,
279 setregs,
280 nothing, /* unlock */
281 nothing, /* lock */
282 vga_test,
283 vgadrv_init,
284 (void (*)(int)) nothing, /* __svgalib_setpage */
285 (void (*)(int)) nothing, /* __svgalib_setrdpage */
286 (void (*)(int)) nothing, /* __svgalib_setwrpage */
287 setmode,
288 modeavailable,
289 setdisplaystart,
290 setlogicalwidth,
291 getmodeinfo,
292 0, /* bitblt */
293 0, /* imageblt */
294 0, /* fillblt */
295 0, /* hlinelistblt */
296 0, /* bltwait */
297 0, /* extset */
298 0,
299 0, /* linear */
300 NULL, /* Accelspecs */
301 NULL, /* Emulation */
302 };
303
304 /* Initialize chipset (called after detection) */
305
vgadrv_init(int force,int par1,int par2)306 static int vgadrv_init(int force, int par1, int par2)
307 {
308 if (__svgalib_driver_report)
309 printf("Using VGA driver.\n");
310 __svgalib_driverspecs = &__svgalib_vga_driverspecs;
311
312 return 0;
313 }
314