1 /*
2  * Copyright 1993 by David Wexelblat <dwex@goblin.org>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of David Wexelblat not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  David Wexelblat makes no representations
11  * about the suitability of this software for any purpose.  It is provided
12  * "as is" without express or implied warranty.
13  *
14  * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL DAVID WEXELBLAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 /*************************************************************************/
24 
25 /*
26  * This is a oak SVGA driver for XFree86.
27  *
28  *  Built from Xfree86 1.3 stub file.
29  * 9/1/93 Initial version Steve Goldman  sgoldman@encore.com
30  *
31  * This one file can be used for both the color and monochrome servers.
32  * Remember that the monochrome server is actually using a 16-color mode,
33  * with only one bitplane active.  To distinguish between the two at
34  * compile-time, use '#ifdef MONOVGA', etc.
35  */
36 
37 /*************************************************************************/
38 
39 /* $XFree86: mit/server/ddx/x386/vga256/drivers/oak/oak_driver.c,v 2.1 1993/10/02 07:16:14 dawes Exp $ */
40 
41 /*
42  * These are X and server generic header files.
43  */
44 #include "X.h"
45 #include "input.h"
46 #include "screenint.h"
47 
48 /*
49  * These are XFree86-specific header files
50  */
51 #include "compiler.h"
52 #include "x386.h"
53 #include "x386Priv.h"
54 #include "xf86_OSlib.h"
55 #include "xf86_HWlib.h"
56 #include "vga.h"
57 
58 /*
59  * Driver data structures.
60  */
61 typedef struct {
62 	/*
63 	 * This structure defines all of the register-level information
64 	 * that must be stored to define a video mode for this chipset.
65 	 * The 'vgaHWRec' member must be first, and contains all of the
66 	 * standard VGA register information, as well as saved text and
67 	 * font data.
68 	 */
69 	vgaHWRec std;               /* good old IBM VGA */
70   	/*
71 	 * Any other registers or other data that the new chipset needs
72 	 * to be saved should be defined here.  The Init/Save/Restore
73 	 * functions will manipulate theses fields.  Examples of things
74 	 * that would go here are registers that contain bank select
75 	 * registers, or extended clock select bits, or extensions to
76 	 * the timing registers.  Use 'unsigned char' as the type for
77 	 * these registers.
78 	 */
79 	unsigned char oakMisc;    	/* Misc register */
80 	unsigned char oakOverflow;    	/* overflow register */
81 	unsigned char oakHsync2;    	/* Hsync/2 start register */
82 	unsigned char oakOverflow2;    	/* overflow2 register */
83 	unsigned char oakConfig;    	/* config 67 vs. 77 */
84 	unsigned char oakBCompat;    	/* backward compatibility */
85 	unsigned char oakBank;    	/* initial bank, debug only */
86 } vgaOAKRec, *vgaOAKPtr;
87 
88 /*
89  * Forward definitions for the functions that make up the driver.  See
90  * the definitions of these functions for the real scoop.
91  */
92 static Bool     OAKProbe();
93 static char *   OAKIdent();
94 static void     OAKClockSelect();
95 static void     OAKEnterLeave();
96 static Bool     OAKInit();
97 extern void *   OAKSave();
98 extern void     OAKRestore();
99 static void     OAKAdjust();
100 static void     OAKSaveScreen();
101 static void     OAKGetMode();
102 /*
103  * These are the bank select functions.  There are defined in oak_bank.s
104  */
105 extern void     OAKSetRead();
106 extern void     OAKSetWrite();
107 extern void     OAKSetReadWrite();
108 
109 /*
110  * This data structure defines the driver itself.  The data structure is
111  * initialized with the functions that make up the driver and some data
112  * that defines how the driver operates.
113  */
114 vgaVideoChipRec OAK = {
115 	/*
116 	 * Function pointers
117 	 */
118 	OAKProbe,
119 	OAKIdent,
120 	OAKEnterLeave,
121 	OAKInit,
122 	OAKSave,
123 	OAKRestore,
124 	OAKAdjust,
125 	NoopDDA,
126 	NoopDDA,
127 	NoopDDA,
128 	OAKSetRead,
129 	OAKSetWrite,
130 	OAKSetReadWrite,
131 	/*
132 	 * This is the size of the mapped memory window, usually 64k.
133 	 */
134 	0x10000,
135 	/*
136 	 * This is the size of a video memory bank for this chipset.
137 	 */
138 	0x10000,
139 	/*
140 	 * This is the number of bits by which an address is shifted
141 	 * right to determine the bank number for that address.
142 	 */
143 	16,
144 	/*
145 	 * This is the bitmask used to determine the address within a
146 	 * specific bank.
147 	 */
148 	0xFFFF,
149 	/*
150 	 * These are the bottom and top addresses for reads inside a
151 	 * given bank.
152 	 */
153 	0x00000, 0x10000,
154 	/*
155 	 * And corresponding limits for writes.
156 	 */
157 	0x00000, 0x10000,
158 	/*
159 	 * Whether this chipset supports a single bank register or
160 	 * separate read and write bank registers.  Almost all chipsets
161 	 * support two banks, and two banks are almost always faster
162 	 * (Trident 8900C and 9000 are odd exceptions).
163 	 */
164 	TRUE, /* two banks */
165 	/*
166 	 * If the chipset requires vertical timing numbers to be divided
167 	 * by two for interlaced modes, set this to VGA_DIVIDE_VERT.
168 	 */
169 	VGA_NO_DIVIDE_VERT,
170 	/*
171 	 * This is a dummy initialization for the set of vendor/option flags
172 	 * that this driver supports.  It gets filled in properly in the
173 	 * probe function, if the probe succeeds (assuming the driver
174 	 * supports any such flags).
175 	 */
176 	{0,},
177 	/*
178 	 * This specifies how the virtual width is to be rounded.  The
179 	 * virtual width will be rounded down the nearest multiple of
180 	 * this value
181 	 */
182 	16,
183 };
184 
185 /*
186  * This is a convenience macro, so that entries in the driver structure
187  * can simply be dereferenced with 'new->xxx'.
188  */
189 #define new ((vgaOAKPtr)vgaNewVideoState)
190 
191 /*
192     A bunch of defines that match Oak's register names
193     so we don't use a bunch of hardcoded constants in the code.
194 */
195 #define OTI_INDEX 0x3DE			/* Oak extended index register */
196 #define OTI_R_W 0x3DF			/* Oak extended r/w register */
197 #define OTI_CRT_CNTL 0xC		/* Oak CRT COntrol Register */
198 #define OTI_MISC  0xD			/* Oak Misc register */
199 #define OTI_BCOMPAT  0xE		/* Oak Back compat register */
200 #define OTI_SEGMENT  0x11		/* Oak segment register */
201 #define OTI_CONFIG  0x12		/* Oak config register */
202 #define OTI_OVERFLOW  0x14		/* Oak overflow register */
203 #define OTI_HSYNC2  0x15		/* Oak hsync/2 start register */
204 #define OTI_OVERFLOW2  0x16		/* Oak overflow2 register */
205 
206 
207 #define OTI67 0   /* same index as ident function */
208 #define OTI77 1   /* same index as ident function */
209 
210 static int OTI_chipset;
211 
212 static unsigned OAK_ExtPorts[] = { OTI_INDEX, OTI_R_W };
213 static int Num_OAK_ExtPorts = (sizeof(OAK_ExtPorts)/sizeof(OAK_ExtPorts[0]));
214 
215 /*
216  * OAKIdent --
217  *
218  * Returns the string name for supported chipset 'n'.  Most drivers only
219  * support one chipset, but multiple version may require that the driver
220  * identify them individually (e.g. the Trident driver).  The Ident function
221  * should return a string if 'n' is valid, or NULL otherwise.  The
222  * server will call this function when listing supported chipsets, with 'n'
223  * incrementing from 0, until the function returns NULL.  The 'Probe'
224  * function should call this function to get the string name for a chipset
225  * and when comparing against an Xconfig-supplied chipset value.  This
226  * cuts down on the number of places errors can creep in.
227  */
228 static char *
OAKIdent(n)229 OAKIdent(n)
230 int n;
231 {
232 	static char *chipsets[] = {"oti067","oti077"};
233 
234 	if (n + 1 > sizeof(chipsets) / sizeof(char *))
235 		return(NULL);
236 	else
237 		return(chipsets[n]);
238 }
239 
240 /*
241  * OAKClockSelect --
242  *
243  * This function selects the dot-clock with index 'no'.  In most cases
244  * this is done my setting the correct bits in various registers (generic
245  * VGA uses two bits in the Miscellaneous Output Register to select from
246  * 4 clocks).  Care must be taken to protect any other bits in these
247  * registers by fetching their values and masking off the other bits.
248  */
249 static void
OAKClockSelect(no)250 OAKClockSelect(no)
251 int no;
252 {
253 	static unsigned char save1,save2;
254 	unsigned char temp;
255 
256 	switch(no)
257 	{
258 	case CLK_REG_SAVE:
259 		/*
260 		 * Here all of the registers that can be affected by
261 		 * clock setting should be saved into static variables.
262 		 */
263 		save1 = inb(0x3CC);
264 		/* Any extended registers would go here */
265 		outb(OTI_INDEX, OTI_MISC);
266 		save2 = inb(OTI_R_W);
267 		break;
268 	case CLK_REG_RESTORE:
269 		/*
270 		 * Here all the previously saved registers are restored.
271 		 */
272 		outb(0x3C2, save1);
273 		/* Any extended registers would go here */
274 		/* all the examples seem to just blast the old data
275 	           in what about any other bit changes?? */
276 		outw(OTI_INDEX, OTI_MISC | (save2 << 8));
277 		break;
278 	default:
279 		/*
280 	 	 * These are the generic two low-order bits of the clock select
281 		 */
282 		temp = inb(0x3CC);
283 		outb(0x3C2, ( temp & 0xF3) | ((no << 2) & 0x0C));
284 		/*
285 	 	 * Here is where the high order bit(s) supported by the chipset
286 	 	 * are set.  This is done by fetching the appropriate register,
287 	 	 * masking off bits that will be changing, then shifting and
288 	 	 * masking 'no' to set the bits as appropriate.
289 	 	 */
290 		outb(OTI_INDEX, OTI_MISC);
291 		temp = inb(OTI_R_W);
292 		outw(OTI_INDEX, OTI_MISC |
293                                 ((( temp & 0xDF ) | (( no & 4) << 3)) << 8));
294 
295 	}
296 }
297 
298 
299 /*
300  * OAKProbe --
301  *
302  * This is the function that makes a yes/no decision about whether or not
303  * a chipset supported by this driver is present or not.  The server will
304  * call each driver's probe function in sequence, until one returns TRUE
305  * or they all fail.
306  *
307  * Pretty much any mechanism can be used to determine the presence of the
308  * chipset.  If there is a BIOS signature (e.g. ATI, GVGA), it can be read
309  * via /dev/mem on most OSs, but some OSs (e.g. Mach) require special
310  * handling, and others (e.g. Amoeba) don't allow reading  the BIOS at
311  * all.  Hence, this mechanism is discouraged, if other mechanisms can be
312  * found.  If the BIOS-reading mechanism must be used, examine the ATI and
313  * GVGA drivers for the special code that is needed.  Note that the BIOS
314  * base should not be assumed to be at 0xC0000 (although most are).  Use
315  * 'vga256InfoRec.BIOSbase', which will pick up any changes the user may
316  * have specified in the Xconfig file.
317  *
318  * The preferred mechanism for doing this is via register identification.
319  * It is important not only the chipset is detected, but also to
320  * ensure that other chipsets will not be falsely detected by the probe
321  * (this is difficult, but something that the developer should strive for).
322  * For testing registers, there are a set of utility functions in the
323  * "compiler.h" header file.  A good place to find example probing code is
324  * in the SuperProbe program, which uses algorithms from the "vgadoc2.zip"
325  * package (available on most PC/vga FTP mirror sites, like ftp.uu.net and
326  * wuarchive.wustl.edu).
327  *
328  * Once the chipset has been successfully detected, then the developer needs
329  * to do some other work to find memory, and clocks, etc, and do any other
330  * driver-level data-structure initialization may need to be done.
331  */
332 static Bool
OAKProbe()333 OAKProbe()
334 {
335 	unsigned char save, temp1;
336 
337 	xf86ClearIOPortList(vga256InfoRec.scrnIndex);
338 	xf86AddIOPorts(vga256InfoRec.scrnIndex, Num_VGA_IOPorts, VGA_IOPorts);
339 	xf86AddIOPorts(vga256InfoRec.scrnIndex, Num_OAK_ExtPorts, OAK_ExtPorts);
340 
341 	/*
342 	 * First we attempt to figure out if one of the supported chipsets
343 	 * is present.
344 	 */
345 	if (vga256InfoRec.chipset)
346 	{
347 		/*
348 		 * This is the easy case.  The user has specified the
349 		 * chipset in the Xconfig file.  All we need to do here
350 		 * is a string comparison against each of the supported
351 		 * names available from the Ident() function.  If this
352 		 * driver supports more than one chipset, there would be
353 		 * nested conditionals here (see the Trident and WD drivers
354 		 * for examples).
355 		 */
356 		if (!StrCaseCmp(vga256InfoRec.chipset, OAKIdent(0))) {
357 			OTI_chipset = OTI67;
358 		} else if (!StrCaseCmp(vga256InfoRec.chipset, OAKIdent(1))) {
359 			OTI_chipset = OTI77;
360       		} else
361 			return (FALSE);
362 		OAKEnterLeave(ENTER);
363     	}
364   	else
365 	{
366 		/*
367 		 * OK.  We have to actually test the hardware.  The
368 		 * EnterLeave() function (described below) unlocks access
369 		 * to registers that may be locked, and for OSs that require
370 		 * it, enables I/O access.  So we do this before we probe,
371 		 * even though we don't know for sure that this chipset
372 		 * is present.
373 		 */
374 		OAKEnterLeave(ENTER);
375 
376 		/*
377 		 * Here is where all of the probing code should be placed.
378 		 * The best advice is to look at what the other drivers are
379 		 * doing.  If you are lucky, the chipset reference will tell
380 		 * how to do this.  Other resources include SuperProbe/vgadoc2,
381 		 * and the Ferraro book.
382 		 */
383 
384 		/* First we see if the segment register is present */
385 		outb(OTI_INDEX, OTI_SEGMENT);
386 		save = inb(OTI_R_W);
387 		/* I assume that one I set the index I can r/w/r/w to
388                    my hearts content */
389                 outb(OTI_R_W, save ^ 0x11);
390 		temp1 = inb(OTI_R_W);
391 		outb(OTI_R_W, save);
392 		if (temp1 != ( save ^ 0x11 )) {
393 			/*
394 			 * Turn things back off if the probe is going to fail.
395 			 * Returning FALSE implies failure, and the server
396 			 * will go on to the next driver.
397 			 */
398 	  		OAKEnterLeave(LEAVE);
399 	  		return(FALSE);
400 		}
401 		/* figure out which chipset */
402 		temp1 = inb(OTI_INDEX);
403 		temp1 &= 0xE0;
404 		switch (temp1) {
405 		    case 0xE0 : /* oti 57 don't know it */
406 		        ErrorF("OAK driver: OTI-57 unsupported\n");
407 	  		OAKEnterLeave(LEAVE);
408 	  		return(FALSE);
409 		    case 0x40 : /* oti 67 */
410 			OTI_chipset = OTI67;
411 			break;
412 		    case 0xA0 : /* oti 77 */
413 			OTI_chipset = OTI77;
414 			break;
415 		    default : /* don't know it */
416 		        ErrorF("OAK driver: unknown chipset\n");
417 	  		OAKEnterLeave(LEAVE);
418 	  		return(FALSE);
419 		}
420     	}
421 
422 	/*
423 	 * If the user has specified the amount of memory in the Xconfig
424 	 * file, we respect that setting.
425 	 */
426   	if (!vga256InfoRec.videoRam) {
427 		/*
428 		 * Otherwise, do whatever chipset-specific things are
429 		 * necessary to figure out how much memory (in kBytes) is
430 		 * available.
431 		 */
432 		outb(OTI_INDEX, OTI_MISC);
433 		temp1 = inb(OTI_R_W);
434 		temp1 &= 0xC0;
435 		if (temp1 == 0xC0 )
436       		    vga256InfoRec.videoRam = 1024;
437 		else if (temp1 == 0x80 )
438       		    vga256InfoRec.videoRam = 512;
439 		else if (temp1 == 0x00 )
440       		    vga256InfoRec.videoRam = 256;
441 		else {
442 		    ErrorF("OAK driver: unknown video memory\n");
443 	  	    OAKEnterLeave(LEAVE);
444 	  	    return(FALSE);
445 		}
446     	}
447 
448 	/*
449 	 * Again, if the user has specified the clock values in the Xconfig
450 	 * file, we respect those choices.
451 	 */
452   	if (!vga256InfoRec.clocks)
453     	{
454 		/*
455 		 * This utility function will probe for the clock values.
456 		 * It is passed the number of supported clocks, and a
457 		 * pointer to the clock-select function.
458 		 */
459       		vgaGetClocks(8, OAKClockSelect);
460     	}
461 
462 	/*
463 	 * Last we fill in the remaining data structures.  We specify
464 	 * the chipset name, using the Ident() function and an appropriate
465 	 * index.  We set a boolean for whether or not this driver supports
466 	 * banking for the Monochrome server.  And we set up a list of all
467 	 * the vendor flags that this driver can make use of.
468 	 */
469   	vga256InfoRec.chipset = OAKIdent(OTI_chipset);
470   	vga256InfoRec.bankedMono = TRUE;
471   	return(TRUE);
472 }
473 
474 /*
475  * OAKEnterLeave --
476  *
477  * This function is called when the virtual terminal on which the server
478  * is running is entered or left, as well as when the server starts up
479  * and is shut down.  Its function is to obtain and relinquish I/O
480  * permissions for the SVGA device.  This includes unlocking access to
481  * any registers that may be protected on the chipset, and locking those
482  * registers again on exit.
483  */
484 static void
OAKEnterLeave(enter)485 OAKEnterLeave(enter)
486 Bool enter;
487 {
488 	static unsigned char save;
489 	unsigned char temp;
490 
491   	if (enter)
492     	{
493 		xf86EnableIOPorts(vga256InfoRec.scrnIndex);
494 
495 		/*
496 		 * This is a global.  The CRTC base address depends on
497 		 * whether the VGA is functioning in color or mono mode.
498 		 * This is just a convenient place to initialize this
499 		 * variable.
500 		 */
501       		vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
502 
503 		/*
504 		 * Here we deal with register-level access locks.  This
505 		 * is a generic VGA protection; most SVGA chipsets have
506 		 * similar register locks for their extended registers
507 		 * as well.
508 		 */
509 
510       		/* Unprotect CRTC[0-7] */
511       		outb(vgaIOBase + 4, 0x11); temp = inb(vgaIOBase + 5);
512       		outb(vgaIOBase + 5, temp & 0x7F);
513 		outb(OTI_INDEX, OTI_CRT_CNTL);
514 		temp = inb(OTI_R_W);
515 		outb(OTI_R_W, temp & 0xF0);
516                 save = temp;
517     	}
518   	else
519     	{
520 		/*
521 		 * Here undo what was done above.
522 		 */
523 		outb(OTI_INDEX, OTI_CRT_CNTL);
524 		/* don't set the i/o write test bit even though
525                    we cleared it on entry */
526 		outb(OTI_R_W, (save & 0xF7) );
527 
528       		/* Protect CRTC[0-7] */
529       		outb(vgaIOBase + 4, 0x11); temp = inb(vgaIOBase + 5);
530       		outb(vgaIOBase + 5, (temp & 0x7F) | 0x80);
531 
532 		xf86DisableIOPorts(vga256InfoRec.scrnIndex);
533     	}
534 }
535 
536 /*
537  * OAKRestore --
538  *
539  * This function restores a video mode.  It basically writes out all of
540  * the registers that have previously been saved in the vgaOAKRec data
541  * structure.
542  *
543  * Note that "Restore" is a little bit incorrect.  This function is also
544  * used when the server enters/changes video modes.  The mode definitions
545  * have previously been initialized by the Init() function, below.
546  */
547 extern void
548 OAKRestore(restore)
549 vgaOAKPtr restore;
550 {
551 	unsigned char temp;
552 
553 	/*
554 	 * Whatever code is needed to get things back to bank zero should be
555 	 * placed here.  Things should be in the same state as when the
556 	 * Save/Init was done.
557 	 */
558 	/* put the segment regs back to zero */
559 	outw(OTI_INDEX, OTI_SEGMENT);
560 
561         /*
562            Set the OTI-Misc register. We must be sure that we
563            aren't in one of the extended graphics modes when
564            we are leaving X and about to call vgaHWRestore for
565            the last time. If we don't text mode is completely
566            fouled up.
567         */
568 	outb(OTI_INDEX, OTI_MISC);
569 	temp = inb(OTI_R_W) & 0x20; /* get the clock bit */
570         temp |= (restore->oakMisc & 0xDF);
571 	outb(OTI_R_W, temp);
572 
573 	/*
574 	 * This function handles restoring the generic VGA registers.
575 	 */
576 	vgaHWRestore(restore);
577 
578 	/*
579 	 * Code to restore any SVGA registers that have been saved/modified
580 	 * goes here.  Note that it is allowable, and often correct, to
581 	 * only modify certain bits in a register by a read/modify/write cycle.
582 	 *
583 	 * A special case - when using an external clock-setting program,
584 	 * this function must not change bits associated with the clock
585 	 * selection.  This condition can be checked by the condition:
586 	 *
587 	 *	if (restore->std.NoClock >= 0)
588 	 *		restore clock-select bits.
589 	 */
590 
591 	outb(OTI_INDEX, OTI_SEGMENT);
592         outb(OTI_R_W, restore->oakBank);
593 
594 	if (restore->std.NoClock >= 0) {
595 		/* restore clock-select bits. */
596 	        outw(OTI_INDEX, OTI_MISC + (restore->oakMisc << 8));
597 	} else {
598 		/* don't restore clock-select bits. */
599 	        outb(OTI_INDEX, OTI_MISC);
600 		temp = inb(OTI_R_W) & 0x20; /* get the clock bit */
601 		temp |= (restore->oakMisc & 0xDF);
602 	        outb(OTI_R_W, temp);
603 	}
604 
605 	outb(OTI_INDEX, OTI_BCOMPAT);
606 	temp = inb(OTI_R_W);
607 	temp &= 0xF9;
608 	temp |= (restore->oakBCompat & 0x6);
609 	outb(OTI_INDEX, OTI_CONFIG);
610 	temp = inb(OTI_R_W);
611 	temp &= 0xF7;
612 	temp |= (restore->oakConfig & 0x8);
613 	outb(OTI_R_W, temp);
614 	outw(OTI_INDEX, OTI_OVERFLOW + (restore->oakOverflow << 8));
615 	outw(OTI_INDEX, OTI_HSYNC2 + (restore->oakHsync2 << 8));
616 
617         if ( OTI_chipset == OTI77)
618 	    outw(OTI_INDEX, OTI_OVERFLOW2 + (restore->oakOverflow2 << 8));
619 
620   	outw(0x3C4, 0x0300); /* now reenable the timing sequencer */
621 
622 }
623 
624 /*
625  * OAKSave --
626  *
627  * This function saves the video state.  It reads all of the SVGA registers
628  * into the vgaOAKRec data structure.  There is in general no need to
629  * mask out bits here - just read the registers.
630  */
631 extern void *
632 OAKSave(save)
633 vgaOAKPtr save;
634 {
635         unsigned char temp;
636 	/*
637 	 * Whatever code is needed to get back to bank zero goes here.
638 	 */
639 	outb(OTI_INDEX, OTI_SEGMENT);
640         temp = inb(OTI_R_W);
641         /* put segment register to zero */
642         outb(OTI_R_W, 0);
643 
644 	/*
645 	 * This function will handle creating the data structure and filling
646 	 * in the generic VGA portion.
647 	 */
648 	save = (vgaOAKPtr)vgaHWSave(save, sizeof(vgaOAKRec));
649 
650 	/*
651 	 * The port I/O code necessary to read in the extended registers
652 	 * into the fields of the vgaOAKRec structure goes here.
653 	 */
654 
655 	save->oakBank = temp; /* this seems silly, leftover from textmode
656 	                         problems */
657 
658 	outb(OTI_INDEX, OTI_MISC);
659 	save->oakMisc = inb(OTI_R_W);
660 	outb(OTI_INDEX, OTI_CONFIG);
661 	save->oakConfig = inb(OTI_R_W);
662 	outb(OTI_INDEX, OTI_BCOMPAT);
663 	save->oakBCompat = inb(OTI_R_W);
664 	outb(OTI_INDEX, OTI_OVERFLOW);
665 	save->oakOverflow = inb(OTI_R_W);
666 	outb(OTI_INDEX, OTI_HSYNC2);
667 	save->oakHsync2 = inb(OTI_R_W);
668         if ( OTI_chipset == OTI77) {
669 	    outb(OTI_INDEX, OTI_OVERFLOW2);
670 	    save->oakOverflow2 = inb(OTI_R_W);
671 	}
672 
673   	return ((void *) save);
674 }
675 
676 /*
677  * OAKInit --
678  *
679  * This is the most important function (after the Probe) function.  This
680  * function fills in the vgaOAKRec with all of the register values needed
681  * to enable either a 256-color mode (for the color server) or a 16-color
682  * mode (for the monochrome server).
683  *
684  * The 'mode' parameter describes the video mode.  The 'mode' structure
685  * as well as the 'vga256InfoRec' structure can be dereferenced for
686  * information that is needed to initialize the mode.  The 'new' macro
687  * (see definition above) is used to simply fill in the structure.
688  */
689 static Bool
OAKInit(mode)690 OAKInit(mode)
691 DisplayModePtr mode;
692 {
693 	if (mode->Flags & V_INTERLACE ) {
694             /*
695 		When in interlace mode cut the vertical numbers in half.
696 		(Try and find that in the manual!)
697 		Could just set VGA_DIVIDE_VERT but we'd have to
698 		test it and do the divides here anyway.
699             */
700             mode->VTotal >>= 1;
701             mode->VDisplay >>= 1;
702             mode->VSyncStart >>= 1;
703             mode->VSyncEnd >>= 1;
704         }
705 	/*
706 	 * This will allocate the datastructure and initialize all of the
707 	 * generic VGA registers.
708 	 */
709 	if (!vgaHWInit(mode,sizeof(vgaOAKRec)))
710 		return(FALSE);
711 
712 	/*
713 	 * Here all of the other fields of 'new' get filled in, to
714 	 * handle the SVGA extended registers.  It is also allowable
715 	 * to override generic registers whenever necessary.
716 	 *
717 	 * A special case - when using an external clock-setting program,
718 	 * this function must not change bits associated with the clock
719 	 * selection.  This condition can be checked by the condition:
720 	 *
721 	 *	if (new->std.NoClock >= 0)
722 	 *		initialize clock-select bits.
723 	 */
724 #ifndef MONOVGA
725 	/* new->std.CRTC[19] = vga256InfoRec.virtualX >> 3; /* 3 in byte mode */
726 	/* much clearer as 0x01 than 0x41, seems odd though... */
727 	new->std.Attribute[16] = 0x01;
728 
729         /*
730             We set the fifo depth to maximum since it seems to
731             remove screen interference at high resolution. This
732             could probably be set to some other value for better
733             performance.
734         */
735         if ( new->std.NoClock >= 0 ) {
736 	    new->oakMisc = 0x0F | ((new->std.NoClock & 0x04) << 3);
737 	} else
738 	    new->oakMisc = 0x0F; /*  high res mode, deep fifo */
739 #else
740         if ( new->std.NoClock >= 0 ) {
741 	    new->oakMisc = 0x18 | ((new->std.NoClock & 0x04) << 3);
742 	} else
743 	    new->oakMisc = 0x18; /*  16 color high res mode */
744 #endif
745 	new->oakBank = 0;
746 	new->oakBCompat = 0x80; /* vga mode */
747 	new->oakConfig = (OTI_chipset == OTI77 ? 0x8 : 0 );
748 	/* set number of ram chips! */                    /* 40 */
749 	new->oakMisc |= (vga256InfoRec.videoRam == 1024 ? 0x40 : 0x00 );
750 	new->oakMisc |= (vga256InfoRec.videoRam >= 512 ? 0x80 : 0x00 );
751 	if (mode->Flags & V_INTERLACE ) {
752 	    new->oakOverflow = 0x80 |
753             /* V-retrace-start */  (((mode->VSyncStart ) & 0x400) >> 8 ) |
754             /* V-blank-start */    ((((mode->VDisplay-1) ) & 0x400) >> 9 ) |
755             /* V-total */          ((((mode->VTotal-2) ) & 0x400) >> 10 ) ;
756 	    /* can set overflow2 no matter what here since restore will
757                do the right thing */
758 	    new->oakOverflow2 = 0;
759             /* Doc. says this is when vertical retrace will start in
760                every odd frame in interlaced mode in characters. Hmm??? */
761 	    new->oakHsync2 =  (mode->VTotal-2) >> 3;
762 	} else {
763 	    new->oakOverflow = (mode->Flags & V_INTERLACE ? 0x80 : 0x00) |
764             /* V-retrace-start */  ((mode->VSyncStart & 0x400) >> 8 ) |
765             /* V-blank-start */    (((mode->VDisplay-1) & 0x400) >> 9 ) |
766             /* V-total */          (((mode->VTotal-2) & 0x400) >> 10 ) ;
767 	    /* can set overflow2 no matter what here since restore will
768                do the right thing */
769 	    new->oakOverflow2 = 0;
770 	    new->oakHsync2 = 0;
771 	}
772 
773         /*
774              Put vertical numbers back so virtual screen doesn't
775              get fooled.
776         */
777 	if (mode->Flags & V_INTERLACE ) {
778             mode->VTotal <<= 1;
779             mode->VDisplay <<= 1;
780             mode->VSyncStart <<= 1;
781             mode->VSyncEnd <<= 1;
782         }
783 
784 
785 	return(TRUE);
786 }
787 
788 /*
789  * OAKAdjust --
790  *
791  * This function is used to initialize the SVGA Start Address - the first
792  * displayed location in the video memory.  This is used to implement the
793  * virtual window.
794  */
795 static void
OAKAdjust(x,y)796 OAKAdjust(x, y)
797 int x, y;
798 {
799         int temp;
800 	/*
801 	 * The calculation for Base works as follows:
802 	 *
803 	 *	(y * virtX) + x ==> the linear starting pixel
804 	 *
805 	 * This number is divided by 8 for the monochrome server, because
806 	 * there are 8 pixels per byte.
807 	 *
808 	 * For the color server, it's a bit more complex.  There is 1 pixel
809 	 * per byte.  In general, the 256-color modes are in word-mode
810 	 * (16-bit words).  Word-mode vs byte-mode is will vary based on
811 	 * the chipset - refer to the chipset databook.  So the pixel address
812 	 * must be divided by 2 to get a word address.  In 256-color modes,
813 	 * the 4 planes are interleaved (i.e. pixels 0,3,7, etc are adjacent
814 	 * on plane 0). The starting address needs to be as an offset into
815 	 * plane 0, so the Base address is divided by 4.
816 	 *
817 	 * So:
818 	 *    Monochrome: Base is divided by 8
819 	 *    Color:
820 	 *	if in word mode, Base is divided by 8
821 	 *	if in byte mode, Base is divided by 4
822 	 *
823 	 * The generic VGA only supports 16 bits for the Starting Address.
824 	 * But this is not enough for the extended memory.  SVGA chipsets
825 	 * will have additional bits in their extended registers, which
826 	 * must also be set.
827 	 */
828 	int Base = (y * vga256InfoRec.virtualX + x + 3) >> 3;
829 
830 	/*
831 	 * These are the generic starting address registers.
832 	 */
833 	outw(vgaIOBase + 4, (Base & 0x00FF00) | 0x0C);
834   	outw(vgaIOBase + 4, ((Base & 0x00FF) << 8) | 0x0D);
835 
836 	/*
837 	 * Here the high-order bits are masked and shifted, and put into
838 	 * the appropriate extended registers.
839 	 */
840   	outb(OTI_INDEX, OTI_OVERFLOW);
841 	temp = inb(OTI_R_W);
842         temp &= 0xF7;
843   	temp |= ((Base & 0x10000) >> (5+8));
844   	outb(OTI_R_W, temp);
845         if ( OTI_chipset == OTI77) {
846   	    outb(OTI_INDEX, OTI_OVERFLOW2);
847 	    temp = inb(OTI_R_W);
848             temp &= 0xF7;
849   	    temp |= ((Base & 0x20000) >> (6 + 8));
850   	    outb(OTI_R_W, temp);
851 	}
852 }
853