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