home *** CD-ROM | disk | FTP | other *** search
- /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen */
- /* */
- /* This library is free software; you can redistribute it and/or */
- /* modify it without any restrictions. This library is distributed */
- /* in the hope that it will be useful, but without any warranty. */
-
- /* Multi-chipset support Copyright (C) 1993 Harm Hanemaayer */
-
- /*
- * Initial ATI Driver January 1995, Scott D. Heavner (sdh@po.cwru.edu)
- */
-
- /* ==== SO FAR THE ONLY SPECIAL THING THIS ATI DRIVER DOES IS ALLOW
- * ==== GRAPHICS MODES TO FUNCTION WITH A 132col TERMINAL, THERE ARE NO
- * ==== NEW MODES YET (there will be). No the XF86 driver won't help as
- * ==== XF863.1 doesn't work properly with my ATI Graphics Ultra,
- * ==== I will be having a look at the XF86 drivers now that I've found
- * ==== the problem an implemented a fix here.
- *
- * ---- If this driver detects a mach32 chip, it does not init the ATI
- * ---- driver, hopefully, the autodetect will find the Mach32 driver.
- * ---- We should probably change this to run the Mach32 as an ATI SVGA
- * ---- board, but probe for the Mach32 first, this would allow the user
- * ---- to force ATI mode in a config file.
- */
-
- #define ATI_UNKNOWN 0
- #define ATI_18800 1
- #define ATI_18800_1 2
- #define ATI_28800_2 3
- #define ATI_28800_4 4
- #define ATI_28800_5 5
- #define ATI_68800 'a'
-
- #define ATIREG(s) (EXT+(s)-0xa0)
-
- #define MIN(a,b) (((a)<(b))?(a):(b))
- #define ABS(a) (((a)<0)?(-(a)):(a))
-
- #include <stdio.h>
- #include <stdlib.h> /* for NULL */
- #include <string.h>
- #include <sys/types.h>
- #include <sys/mman.h>
- #include <fcntl.h>
- #include <unistd.h>
-
- #include "vga.h"
- #include "libvga.h"
- #include "driver.h"
-
- static unsigned char ati_flags_42, ati_flags_44, ati_gate;
- static short ati_base=0;
-
- static int nothing() { return 0; }
-
- /* Initialize chipset (called after detection) */
- static int ati_init( int force, int par1, int par2) {
- if (__svgalib_driver_report)
- printf("Using ATI (mostly VGA) driver.\n");
- driverspecs = &ati_driverspecs;
-
- /* Have to give ourselves some more permissions -- last port currently used is 0x3df */
- if (ioperm(MIN(ati_base,0x3df), ABS(0x3df-ati_base), 1) ) {
- printf("IOPERM FAILED IN ATI\n");
- exit(-2);
- }
-
- return 1;
- }
-
- /* Read and store chipset-specific registers */
- static int ati_saveregs(unsigned char regs[])
- {
- outb(ati_base,0xb8);
- regs[ATIREG(0xb8)]=inb(1+ati_base);
-
- if (ati_gate>ATI_18800) {
- outb(ati_base,0xbe);
- regs[ATIREG(0xbe)]=inb(1+ati_base);
- }
-
- return 0;
- }
-
- /* Set chipset-specific registers */
- static int ati_setregs( const unsigned char regs[], int mode )
- {
- unsigned char c;
-
- if (mode==TEXT) { /* Death request */
- outb(ati_base,0xb8);
- outb(1+ati_base, regs[ATIREG(0xb8)]);
-
- if (ati_gate>ATI_18800) {
- outb(ati_base,0xbe);
- outb(1+ati_base, regs[ATIREG(0xbe)]);
- }
- } else {
- /* Mess with the timings before passing it off to the vga driver */
- outb(ati_base,0xb8);
- c = inb(1+ati_base) | 0x40;
- outb(1+ati_base, c);
-
- if (ati_gate>ATI_18800) {
- outb(ati_base,0xbe);
- c = inb(1+ati_base) | 0x10;
- outb(1+ati_base, c);
- }
-
- }
- return 0;
- }
-
- /* Fill in chipset specific mode information */
- static void ati_getmodeinfo( int mode, vga_modeinfo *modeinfo ) {
- vga_driverspecs.getmodeinfo(mode, modeinfo);
- }
-
-
- /* Return non-zero if mode is available */
- static void ati_modeavailable( int mode ) {
- vga_driverspecs.modeavailable(mode);
- }
-
-
- /* Set a mode */
- static int ati_setmode( int mode, int prv_mode ) {
- const unsigned char *regs = NULL;
- ati_setregs(regs, mode);
- return vga_driverspecs.setmode(mode, prv_mode);
- }
-
- /* Lifted from the genoa driver, maybe we should let everyone do the checks while we have
- * the vbios mmapped */
- static unsigned char *map_vbios()
- {
- unsigned char *vga_bios;
-
- /* Changed to use valloc(). */
- if ((vga_bios = valloc(4096)) == NULL)
- {
- fprintf (stderr, "svgalib: malloc error\n");
- exit (-1);
- }
-
- vga_bios = (unsigned char *) mmap
- (
- (caddr_t) vga_bios,
- 4096,
- PROT_READ,
- MAP_SHARED | MAP_FIXED,
- __svgalib_mem_fd,
- 0xc0000
- );
-
- if ((long) vga_bios < 0)
- {
- fprintf (stderr, "svgalib: mmap error\n");
- exit (-1);
- }
-
- return vga_bios;
- }
-
- static int ati_test()
- {
- int result;
- unsigned char *vga_bios;
-
- vga_bios = map_vbios();
-
- if ( strncmp("761295520",(vga_bios+0x31),9)|| /* Identify as an ATI product */
- strncmp("31",(vga_bios+0x40),2)) { /* Identify as an ATI super vga (vs EGA/Basic-16) */
- result=0;
- } else {
- result=1;
-
- memcpy(&ati_base,(vga_bios+0x10),2);
-
- switch (vga_bios[0x43]) { /* Identify Gate revision */
- case '1':
- ati_gate = ATI_18800;
- break;
- case '2':
- ati_gate = ATI_18800_1;
- break;
- case '3':
- ati_gate = ATI_28800_2;
- break;
- case '4':
- ati_gate = ATI_28800_4;
- break;
- case '5':
- ati_gate = ATI_28800_5;
- break;
- case 'a':
- ati_gate = ATI_68800; /* Mach 32, should someone else handle this ? */
- return 0;
- default:
- ati_gate = ATI_UNKNOWN;
- }
-
- ati_flags_42 = vga_bios[0x42];
- ati_flags_44 = vga_bios[0x44];
-
- }
-
- if (result)
- result = ati_init(0,0,0);
-
- munmap ((caddr_t) vga_bios, 4096);
-
- return (result);
-
- }
-
-
- /* Set display start */
- static void ati_setdisplaystart( int address ) {
- vga_driverspecs.setdisplaystart(address);
- }
-
-
- /* Set logical scanline length (usually multiple of 8) */
- static void ati_setlogicalwidth( int width ) {
- vga_driverspecs.setlogicalwidth(width);
- }
-
-
- /* Function table (exported) */
- DriverSpecs ati_driverspecs = {
- ati_saveregs,
- ati_setregs,
- nothing, /* unlock */
- nothing, /* lock */
- ati_test,
- ati_init,
- nothing, /* setpage */
- nothing, /* setrdpage */
- nothing, /* setwrpage */
- ati_setmode,
- ati_modeavailable,
- ati_setdisplaystart,
- ati_setlogicalwidth,
- ati_getmodeinfo,
- 0, /* bitblt */
- 0, /* imageblt */
- 0, /* fillblt */
- 0, /* hlinelistblt */
- 0, /* bltwait */
- 0, /* extset */
- 0,
- 0, /* linear */
- NULL /* accelspecs */
- };
-