示例#1
0
/*
 * ibm8514Probe --
 *     probe and initialize the hardware driver
 */
Bool
ibm8514Probe()
{
    OFlagSet       validOptions;

    xf86ClearIOPortList(ibm8514InfoRec.scrnIndex);
    xf86AddIOPorts(ibm8514InfoRec.scrnIndex, Num_ibm8514_IOPorts,
		   ibm8514_IOPorts);

    if (ibm8514InfoRec.chipset) {
	if (StrCaseCmp(ibm8514InfoRec.chipset, "ibm8514")) {
	    ErrorF("Chipset specified in XF86Config is not \"ibm8514\" (%s)!\n",
		   ibm8514InfoRec.chipset);
	    return(FALSE);
	}
	xf86EnableIOPorts(ibm8514InfoRec.scrnIndex);
    }
    else
    {
	xf86EnableIOPorts(ibm8514InfoRec.scrnIndex);

	/* Reset the 8514/A, and disable all interrupts. */
	outw(SUBSYS_CNTL, GPCTRL_RESET | CHPTEST_NORMAL);
	outw(SUBSYS_CNTL, GPCTRL_ENAB | CHPTEST_NORMAL);

	/* Check to see if an 8514/A is actually installed by writing to
	 * the ERR_TERM register, and reading back.  The 0x5a5a value is
	 * entirely arbitrary.
	 */
	outw(ERR_TERM, 0x5a5a);
	if (inw(ERR_TERM) != 0x5a5a) {
	    xf86DisableIOPorts(ibm8514InfoRec.scrnIndex);
	    return(FALSE);
	}
	/* 6 mar 93 TCG : let's make certain */
	outw(ERR_TERM, 0x5555);
	if (inw(ERR_TERM) != 0x5555) {
	    xf86DisableIOPorts(ibm8514InfoRec.scrnIndex);
	    return(FALSE);
	}
    }
    ibm8514InfoRec.chipset = "ibm8514";
    xf86ProbeFailed = FALSE;

    OFLG_ZERO(&validOptions);
    xf86VerifyOptions(&validOptions, &ibm8514InfoRec);

    return(TRUE);
}
示例#2
0
void ibm8514CleanUp(void)
{
    int i;

    if (LUTInited != -1) {
	outb(DAC_W_INDEX, 0);
	for (i = 0; i < 256; i++) {
	    outb(DAC_DATA, oldlut[i].r);
	    outb(DAC_DATA, oldlut[i].g);
	    outb(DAC_DATA, oldlut[i].b);
	}
    }

    if (old_DAC_MASK != -1) {
	outb(DAC_MASK, old_DAC_MASK);
    }
    outw(ADVFUNC_CNTL, 6);

    xf86DisableIOPorts(ibm8514InfoRec.scrnIndex);
}
示例#3
0
void
s3CleanUp(void)
{
   int   i;
   unsigned char tmp;

   outb(vgaCRIndex, 0x39);
   outb(vgaCRReg, 0xa5);

   if (s3MmioMem != NULL ) {
      WaitIdle();
      VerticalRetraceWait();
      ((mmtr)s3MmioMem)->memport_regs.regs.fifo_control = oldS3->fifo[0];
      WaitIdle();                  /* Don't ask... */
      ((mmtr)s3MmioMem)->memport_regs.regs.streams_timeout = oldS3->fifo[1];
   }

   #if 1			   
   			/* This seems to help, but maybe a wait for */
			/* VSYNC would be better than WaitIdleEmpty(). */
   				/* STREAMS disable code, for 24 & 32 Bpp */
   if ( ( s3InfoRec.bitsPerPixel == 32 || 
          s3InfoRec.bitsPerPixel == 24 ) &&
          s3MmioMem != NULL ) {
	  			/* temp - KJB */
       ((mmtr)s3MmioMem)->streams_regs.regs.prim_fbaddr0 = 0;
	      /*  ((y * s3DisplayWidth + (x & ~3)) * s3Bpp) */ /* & ~3 */;
	      			/* end temp */
       
       outb(vgaCRIndex, 0x67);
       tmp = inb(vgaCRReg);
       /* WaitIdleEmpty(); */
 				/* Disable STREAMS processor */
       outb( vgaCRReg, tmp & ~0x0C );
   }	
   #endif

   vgaProtect(TRUE);

   if (s3NewMmio)	{
      outb (vgaCRIndex, 0x58);
      outb (vgaCRReg, s3SAM256); /* disable linear mode */
   } /* end BL */


   WaitQueue(8);
   outb(vgaCRIndex, 0x35);
   tmp = inb(vgaCRReg);
   outb(vgaCRReg, (tmp & 0xf0));
   cebank();

   if (s3NewMmio) {
      outb(vgaCRIndex, 0x53);
      outb(vgaCRReg, 0x00);
   }

   /* Restore S3 Trio32/64 ext. sequenzer (PLL) registers */
   if (DAC_IS_TRIO)
   {
      outb(0x3c2, oldS3->Trio[0]);
      outb(0x3c4, 0x08); outb(0x3c5, 0x06);

      outb(0x3c4, 0x09); outb(0x3c5, oldS3->Trio[2]);
      outb(0x3c4, 0x0a); outb(0x3c5, oldS3->Trio[3]);
      outb(0x3c4, 0x0b); outb(0x3c5, oldS3->Trio[4]);
      outb(0x3c4, 0x0d); outb(0x3c5, oldS3->Trio[5]);

      outb(0x3c4, 0x10); outb(0x3c5, oldS3->Trio[8]);
      outb(0x3c4, 0x11); outb(0x3c5, oldS3->Trio[9]);
      outb(0x3c4, 0x12); outb(0x3c5, oldS3->Trio[10]);
      outb(0x3c4, 0x13); outb(0x3c5, oldS3->Trio[11]);
      outb(0x3c4, 0x1a); outb(0x3c5, oldS3->Trio[12]);
      outb(0x3c4, 0x1b); outb(0x3c5, oldS3->Trio[13]);
      outb(0x3c4, 0x15);
      tmp = inb(0x3c5) & ~0x21;
      outb(0x3c5, tmp | 0x03);
      outb(0x3c5, tmp | 0x23);
      outb(0x3c5, tmp | 0x03);

      outb(0x3c4, 0x15); outb(0x3c5, oldS3->Trio[6]);
      outb(0x3c4, 0x18); outb(0x3c5, oldS3->Trio[7]);

      outb(0x3c4, 0x08); outb(0x3c5, oldS3->Trio[1]);

   }



   /* restore s3 special bits */

   /* restore 801 specific registers */

   for (i = 32; i < 46; i++) {
      outb(vgaCRIndex, 0x40 + i);
      outb(vgaCRReg, oldS3->s3sysreg[i]);

   }
   for (i = 0; i < 16; i++) {
      if (!((1 << i) & reg50_mask))
	 continue;
      outb(vgaCRIndex, 0x50 + i);
      outb(vgaCRReg, oldS3->s3sysreg[i + 16]);
   }
   for (i = 0; i < 5; i++) {
      outb(vgaCRIndex, 0x30 + i);
      outb(vgaCRReg, oldS3->s3reg[i]);
      outb(vgaCRIndex, 0x38 + i);
      outb(vgaCRReg, oldS3->s3reg[5 + i]);
   }
   outb(vgaCRIndex, 0x36);
   outb(vgaCRReg, oldS3->s3reg[10]);


   for (i = 0; i < 16; i++) {
      outb(vgaCRIndex, 0x40 + i);
      outb(vgaCRReg, oldS3->s3sysreg[i]);
   }

   outb(vgaCRIndex, 0x45);
   inb(vgaCRReg);         /* reset color stack pointer */
   outb(vgaCRIndex, 0x4A);
   for (i = 0; i < 4; i++)
      outb(vgaCRReg, oldS3->ColorStack[i]);

   outb(vgaCRIndex, 0x45);
   inb(vgaCRReg);         /* reset color stack pointer */
   outb(vgaCRIndex, 0x4B);
   for (i = 4; i < 8; i++)
      outb(vgaCRReg, oldS3->ColorStack[i]);


   if (OFLG_ISSET(CLOCK_OPTION_ICS2595, &s3InfoRec.clockOptions)){
      outb(vgaCRIndex, 0x42);
      outb(vgaCRReg, (oldS3->s3sysreg[2] & 0xf0) | 0x01);
      outb(vgaCRIndex, 0x5c);	/* switch back to 28MHz clock */
      outb(vgaCRReg,   0x20);
      outb(vgaCRReg,   0x00);
   }

   vgaHWRestore((vgaHWPtr)oldS3);

   outb(0x3c2, old_clock);

   i = inb(0x3CC);
   if (savedVgaIOBase == 0x3B0)
      i &= 0xFE;
   else
      i |= 0x01;
   outb(0x3C2, i);

   vgaIOBase = savedVgaIOBase;
   vgaCRIndex = vgaIOBase + 4;
   vgaCRReg = vgaIOBase + 5;

   vgaProtect(FALSE);

#ifdef PC98
	crtswitch(0);
#endif

   xf86DisableIOPorts(s3InfoRec.scrnIndex);
}
示例#4
0
文件: xf86_PCI.c 项目: berkus/nemesis
void
xf86scanpci()
{
    unsigned long tmplong1, tmplong2, config_cmd;
    unsigned char tmp1, tmp2;
    unsigned int i, j, idx = 0;
    struct pci_config_reg pcr;
    unsigned PCI_CtrlIOPorts[] = { 0xCF8, 0xCFA, 0xCFC };
    int Num_PCI_CtrlIOPorts = 3;
    unsigned PCI_DevIOPorts[16];
    int Num_PCI_DevIOPorts = 16;
    unsigned PCI_DevIOAddrPorts[16*16];
    int Num_PCI_DevIOAddrPorts = 16*16;

    for (i=0; i<16; i++) {
        PCI_DevIOPorts[i] = 0xC000 + (i*0x0100);
        for (j=0; j<16; j++)
            PCI_DevIOAddrPorts[(i*16)+j] = PCI_DevIOPorts[i] + (j*4);
    }

    xf86ClearIOPortList(0);
    xf86AddIOPorts(0, Num_PCI_CtrlIOPorts, PCI_CtrlIOPorts);
    xf86AddIOPorts(0, Num_PCI_DevIOPorts, PCI_DevIOPorts);
    xf86AddIOPorts(0, Num_PCI_DevIOAddrPorts, PCI_DevIOAddrPorts);

    /* Enable I/O access */
    xf86EnableIOPorts(0);

    outb(0xCF8, 0x00);
    outb(0xCFA, 0x00);
    tmp1 = inb(0xCF8);
    tmp2 = inb(0xCFA);
    if ((tmp1 == 0x00) && (tmp2 == 0x00)) {
	pcr._configtype = 2;
#ifdef DEBUGPCI
        printf("PCI says configuration type 2\n");
#endif
    } else {
        tmplong1 = inl(0xCF8);
        outl(0xCF8, PCI_EN);
        tmplong2 = inl(0xCF8);
        outl(0xCF8, tmplong1);
        if (tmplong2 == PCI_EN) {
	    pcr._configtype = 1;
#ifdef DEBUGPCI
            printf("PCI says configuration type 1\n");
#endif
	} else {
	    pcr._configtype = 0;
#ifdef DEBUGPCI
            printf("No PCI !\n");
#endif
            xf86DisableIOPorts(0);
            xf86ClearIOPortList(0);
	    return;
	}
    }

    /* Try pci config 1 probe first */

#ifdef DEBUGPCI
    printf("\nPCI probing configuration type 1\n");
#endif

    pcr._pcibuses[0] = 0;
    pcr._pcinumbus = 1;
    pcr._pcibusidx = 0;

#ifndef DEBUGPCI
    if (pcr._configtype == 1)
#endif
    do {
        for (pcr._cardnum = 0x0; pcr._cardnum < 0x20; pcr._cardnum += 0x1) {
	    config_cmd = PCI_EN | (pcr._pcibuses[pcr._pcibusidx]<<16) |
                                  (pcr._cardnum<<11);

            outl(0xCF8, config_cmd);         /* ioreg 0 */
            pcr._device_vendor = inl(0xCFC);

            if (pcr._vendor == 0xFFFF)   /* nothing there */
                continue;

#ifdef DEBUGPCI
	    printf("\npci bus 0x%x cardnum 0x%02x, vendor 0x%04x device 0x%04x\n",
	        pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, pcr._vendor,
                pcr._device);
#endif

            outl(0xCF8, config_cmd | 0x04); pcr._status_command  = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x08); pcr._class_revision  = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x0C); pcr._bist_header_latency_cache
								= inl(0xCFC);
            outl(0xCF8, config_cmd | 0x10); pcr._base0  = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x14); pcr._base1  = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x18); pcr._base2  = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x1C); pcr._base3  = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x20); pcr._base4  = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x24); pcr._base5  = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x30); pcr._baserom = inl(0xCFC);
            outl(0xCF8, config_cmd | 0x3C); pcr._max_min_ipin_iline
								= inl(0xCFC);

            /* check for pci-pci bridges (currently we only know Digital) */
            if ((pcr._vendor == 0x1011) && (pcr._device == 0x0001))
                if (pcr._secondary_bus_number > 0)
                    pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number;

	    if (idx >= MAX_PCI_DEVICES)
	        continue;

	    if ((pci_devp[idx] = (struct pci_config_reg *)xalloc(sizeof(
		 struct pci_config_reg))) == (struct pci_config_reg *)NULL) {
                outl(0xCF8, 0x00);
                xf86DisableIOPorts(0);
                xf86ClearIOPortList(0);
		return;
	    }

	    memcpy(pci_devp[idx++], &pcr, sizeof(struct pci_config_reg));
        }
    } while (++pcr._pcibusidx < pcr._pcinumbus);

#ifndef DEBUGPCI
    if (pcr._configtype == 1) {
        outl(0xCF8, 0x00);
	return;
    }
#endif
    /* Now try pci config 2 probe (deprecated) */

    outb(0xCF8, 0xF1);
    outb(0xCFA, 0x00); /* bus 0 for now */

#ifdef DEBUGPCI
    printf("\nPCI probing configuration type 2\n");
#endif

    pcr._pcibuses[0] = 0;
    pcr._pcinumbus = 1;
    pcr._pcibusidx = 0;

    do {
        for (pcr._ioaddr = 0xC000; pcr._ioaddr < 0xD000; pcr._ioaddr += 0x0100){
	    outb(0xCFA, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */
            pcr._device_vendor = inl(pcr._ioaddr);
	    outb(0xCFA, 0x00); /* bus 0 for now */

            if (pcr._vendor == 0xFFFF)   /* nothing there */
                continue;
	    /* opti chipsets that use config type 1 look like this on type 2 */
            if ((pcr._vendor == 0xFF00) && (pcr._device == 0xFFFF))
                continue;

#ifdef DEBUGPCI
	    printf("\npci bus 0x%x slot at 0x%04x, vendor 0x%04x device 0x%04x\n",
	        pcr._pcibuses[pcr._pcibusidx], pcr._ioaddr, pcr._vendor,
                pcr._device);
#endif

	    outb(0xCFA, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */
            pcr._status_command = inl(pcr._ioaddr + 0x04);
            pcr._class_revision = inl(pcr._ioaddr + 0x08);
            pcr._bist_header_latency_cache = inl(pcr._ioaddr + 0x0C);
            pcr._base0 = inl(pcr._ioaddr + 0x10);
            pcr._base1 = inl(pcr._ioaddr + 0x14);
            pcr._base2 = inl(pcr._ioaddr + 0x18);
            pcr._base3 = inl(pcr._ioaddr + 0x1C);
            pcr._base4 = inl(pcr._ioaddr + 0x20);
            pcr._base5 = inl(pcr._ioaddr + 0x24);
            pcr._baserom = inl(pcr._ioaddr + 0x30);
            pcr._max_min_ipin_iline = inl(pcr._ioaddr + 0x3C);
	    outb(0xCFA, 0x00); /* bus 0 for now */

            /* check for pci-pci bridges (currently we only know Digital) */
            if ((pcr._vendor == 0x1011) && (pcr._device == 0x0001))
                if (pcr._secondary_bus_number > 0)
                    pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number;

	    if (idx >= MAX_PCI_DEVICES)
	        continue;

	    if ((pci_devp[idx] = (struct pci_config_reg *)xalloc(sizeof(
		 struct pci_config_reg))) == (struct pci_config_reg *)NULL) {
                outb(0xCF8, 0x00);
                outb(0xCFA, 0x00);
                xf86DisableIOPorts(0);
                xf86ClearIOPortList(0);
		return;
	    }

	    memcpy(pci_devp[idx++], &pcr, sizeof(struct pci_config_reg));
	}
    } while (++pcr._pcibusidx < pcr._pcinumbus);

    outb(0xCF8, 0x00);
    outb(0xCFA, 0x00);

    xf86DisableIOPorts(0);
    xf86ClearIOPortList(0);
}
示例#5
0
static void 
NEC480EnterLeave(Bool enter)
{
	static int flag = 0;
	static int graph_mode, hsync31, cont_page;

	if(flag == 0)
	{
		if (enter == ENTER)
			xf86EnableIOPorts(vga256InfoRec.scrnIndex);
		/* Save current graphic mode, 1: Extended graphic mode */
		outb(0x9a0, 0x0a);
		graph_mode = inb(0x9a0) & 0x01;
		/* Save current G-VRAM page status, 1: continuation */
		outb(0x9a0, 0x0d);
		cont_page = inb(0x9a0) & 0x01;
		/* Save current horizontal sync, 1: 31.5KHz */
		if( vga256InfoRec.clock[0] == NEC480_MAX_CLOCK_IN_KHZ ){
			hsync31 = inb(0x9a8) & 0x01;
		}
		flag = 1;
	}

	if(enter == ENTER)
	{
		if (flag != 0)
			xf86EnableIOPorts(vga256InfoRec.scrnIndex);
		while (!(inb(0x60) & 0x20)) ;	/* V-SYNC wait */
		outb(0x62, 0xc);		/* text off */
		outb(0xA2, 0xc);		/* graphics off */
		/* GDC : 5MHz mode */
		outb(0x6a, 0x83);
		outb(0x6a, 0x85);
		if( vga256InfoRec.clock[0] == NEC480_MAX_CLOCK_IN_KHZ ){
			gdc_init();
		}
		outb(0x6a, 0x07);
		outb(0x6a, 0x21);		/* Extended mode */
		outb(0x6a, 0x69);		/* Continuous G-VRAM page */
		if( vga256InfoRec.clock[0] == NEC480_MAX_CLOCK_IN_KHZ ){
			outb(0x9a8, 0x01);	/* 24.8KHz -> 31.5KHz */
		}
		while (!(inb(0x60) & 0x20)) ;	/* V-SYNC wait */
		outb(0x62, 0xc);		/* text off */
		outb(0xA2, 0xd);		/* graphics on */
	}
	if(enter == LEAVE)
	{
		if(graph_mode == 0)
		{
			outb(0x6a, 0x07);
			outb(0x6a, 0x20);	/* Standard mode */
		}
		if(cont_page == 0)
		{
			outb(0x6a, 0x07);
			outb(0x6a, 0x68);	/* separate VRAM page */
		}
		if( vga256InfoRec.clock[0] == NEC480_MAX_CLOCK_IN_KHZ
		   && hsync31==0 ){
			outb(0x9a8, 0x00);	/* 31.5KHz-> 24.8KHz */
		}
		outb(0xA2, 0xc);		/* graphics off */
		outb(0x62, 0xd);		/* text on */
		*ppmodep = ppmode_sv;
		xf86DisableIOPorts(vga256InfoRec.scrnIndex);
	}
}
示例#6
0
/*
 * mach8Probe --
 *     probe and initialize the hardware driver
 */
Bool
mach8Probe()
{
    int            j, memavail, rounding;
    short          temp;
    DisplayModePtr pMode, pEnd, pmaxX = NULL, pmaxY = NULL;
    int            maxX, maxY;
    OFlagSet       validOptions;
    int            tx, ty;

    mach8InfoRec.maxClock = mach8MaxClock;

    xf86ClearIOPortList(mach8InfoRec.scrnIndex);
    xf86AddIOPorts(mach8InfoRec.scrnIndex, Num_mach8_IOPorts, mach8_IOPorts);

    if (mach8InfoRec.chipset) {
	if (StrCaseCmp(mach8InfoRec.chipset, "mach8")) {
	    ErrorF("Chipset specified in XF86Config is not \"mach8\" (%s)!\n",
		   mach8InfoRec.chipset);
	    return(FALSE);
	}
	xf86EnableIOPorts(mach8InfoRec.scrnIndex);
    }
    else
    {
	xf86EnableIOPorts(mach8InfoRec.scrnIndex);

	/* Reset the 8514/A, and disable all interrupts. */
	outw(SUBSYS_CNTL, GPCTRL_RESET | CHPTEST_NORMAL);
	outw(SUBSYS_CNTL, GPCTRL_ENAB | CHPTEST_NORMAL);

	/* Check to see if an 8514/A is actually installed by writing to
	 * the ERR_TERM register, and reading back.  The 0x5a5a value is
	 * entirely arbitrary.
	 */
	outw(ERR_TERM, 0x5a5a);
	ProbeWaitIdleEmpty();
	if (inw(ERR_TERM) != 0x5a5a) {
	    ErrorF("%s: No 8514/A registers detected!\n", mach8InfoRec.name);
	    xf86DisableIOPorts(mach8InfoRec.scrnIndex);
	    return(FALSE);
	}
	/* 6 mar 93 TCG : let's make certain */
	outw(ERR_TERM, 0x2525);
	ProbeWaitIdleEmpty();
	if (inw(ERR_TERM) != 0x2525) {
	    ErrorF("%s: No 8514/A registers detected!\n", mach8InfoRec.name);
	    xf86DisableIOPorts(mach8InfoRec.scrnIndex);
	    return(FALSE);
	}

	temp = inw(ROM_ADDR_1);
	outw(ROM_ADDR_1, 0x5555);
	ProbeWaitIdleEmpty();
	if (inw(ROM_ADDR_1) != 0x5555) {
	    ErrorF("%s: No ATI accelerator detected\n", mach8InfoRec.name);
	    xf86DisableIOPorts(mach8InfoRec.scrnIndex);
	    return(FALSE);
	}
	outw(ROM_ADDR_1, 0x2a2a);
	ProbeWaitIdleEmpty();
	if (inw(ROM_ADDR_1) != 0x2a2a) {
	    ErrorF("%s: No ATI accelerator detected\n", mach8InfoRec.name);
	    xf86DisableIOPorts(mach8InfoRec.scrnIndex);
	    return(FALSE);
	}
	outw(ROM_ADDR_1, temp);

	outw(DESTX_DIASTP, 0xaaaa);
	ProbeWaitIdleEmpty();
	if ((inw(READ_SRC_X) != 0xaaaa) && xf86Verbose) {
	    outw(DESTX_DIASTP, 0x5555);
	    ProbeWaitIdleEmpty();
	    if (inw(READ_SRC_X) == 0x0555) {
		ErrorF("%s %s: Mach-32 detected, used as a Mach-8\n",
			XCONFIG_PROBED, mach8InfoRec.name);
	    }
	    else
		ErrorF("%s %s: Mach-8 detected\n", XCONFIG_PROBED,
			mach8InfoRec.name);
	}
    }

    OFLG_ZERO(&validOptions);
    OFLG_SET(OPTION_CSYNC, &validOptions);
    xf86VerifyOptions(&validOptions, &mach8InfoRec);

    if (!mach8InfoRec.clocks)
    {
	outw(DISP_CNTL, DISPEN_DISAB /*| INTERLACE*/ | MEMCFG_4 | ODDBNKENAB);
	/* 13-jun-93 TCG : set up dummy video mode */
	outw(SHADOW_SET, 1);
	outw(SHADOW_CTL, 0);
	outw(SHADOW_SET, 2);
	outw(SHADOW_CTL, 0);
	outw(SHADOW_SET, 0);
	outw(ADVFUNC_CNTL, DISABPASSTHRU);

	/* vt: 480 488 +31 528 hz: 640 656 +248 920 */
	outw(V_TOTAL, 0x420);
	outw(V_DISP, 0x3c0);
	outw(V_SYNC_STRT, 0x3d0);
	outw(V_SYNC_WID, 0x1f);
	outw(H_TOTAL, 0x72);
	outw(H_DISP, 0x4f);
	outw(H_SYNC_STRT, 0x51);
	outw(H_SYNC_WID, 0x1f);

	outw(DAC_MASK, 0x00);
	outw(DISP_CNTL, DISPEN_ENAB | MEMCFG_4 | ODDBNKENAB);

	/* 2-oct-93 TCG : detect clocks with dif4 fix */
	mach8clkprobedif4fix = TRUE;
	xf86GetClocks(16, mach8ClockSelect, (void (*)())NoopDDA,
			(SaveScreenProcPtr)NoopDDA, DISP_STAT, 2, 7, 44900,
			&mach8InfoRec);
	outw(CLOCK_SEL, 0); /* reset pass-through */
	mach8clkprobedif4fix = FALSE;

	outw(SHADOW_SET, 1);
	outw(SHADOW_CTL, 0x3f);
	outw(SHADOW_SET, 2);
	outw(SHADOW_CTL, 0x3f);
	outw(SHADOW_SET, 0);

	outw(DAC_MASK, 0xff);

	for (j = 0; j < 16; j++)
	    mach8InfoRec.clock[j + 16] = mach8InfoRec.clock[j] / 2;

	mach8InfoRec.clocks = 32;
    }

    temp = inw(CONFIG_STATUS_1);
    if (!mach8InfoRec.videoRam) {
        switch((temp & 0x60) >> 5)
        {
            case 0:
                mach8InfoRec.videoRam = 512;
                break;
            case 1:
                mach8InfoRec.videoRam = 1024;
                break;
            default: /* 2 & 3 reserved in mach-8, used in mach-32 ? */
                mach8InfoRec.videoRam = 1024;
                break;
        }
    }

    mach8InfoRec.chipset = "mach8";
    xf86ProbeFailed = FALSE;
    mach8DramUsed = (temp & 0x10) != 0;
    if (xf86Verbose)
    {
        ErrorF("%s %s: (mem: %dk %cRAM numclocks: %d)",
               OFLG_ISSET(XCONFIG_VIDEORAM,&mach8InfoRec.xconfigFlag) ?
               XCONFIG_GIVEN : XCONFIG_PROBED,
               mach8InfoRec.name,
               mach8InfoRec.videoRam,
               mach8DramUsed ? 'D' : 'V',
               mach8InfoRec.clocks);

        for (j=0; j < mach8InfoRec.clocks; j++)
        {
            if ((j % 8) == 0)
                ErrorF("\n%s %s: clocks:", 
                   OFLG_ISSET(XCONFIG_CLOCKS,&mach8InfoRec.xconfigFlag) ?
                   XCONFIG_GIVEN : XCONFIG_PROBED,
                   mach8InfoRec.name);
            ErrorF(" %6.2f", (double)mach8InfoRec.clock[j]/1000.0);
        }
        ErrorF("\n");
    }

    memavail = mach8InfoRec.videoRam*1024;
    if (mach8InfoRec.virtualX > 0 &&
        mach8InfoRec.virtualX * mach8InfoRec.virtualY > memavail)
    {
        ErrorF("%s: Too little memory for virtual resolution %d %d\n",
               mach8InfoRec.name, mach8InfoRec.virtualX,
               mach8InfoRec.virtualY);
        return(FALSE);
    }

    maxX = maxY = -1;
    pMode = mach8InfoRec.modes;
    if (pMode == NULL) {
        ErrorF("No modes supplied in XF86Config\n");
        return(FALSE);
    }
    pEnd = NULL;
    tx = mach8InfoRec.virtualX;
    ty = mach8InfoRec.virtualY;
    do {
	  DisplayModePtr pModeSv;
	  /*
	   * xf86LookupMode returns FALSE if it ran into an invalid
	   * parameter
	   */
	  if(xf86LookupMode(pMode, &mach8InfoRec, LOOKUP_DEFAULT) == FALSE) {
		pModeSv=pMode->next;
		xf86DeleteMode(&mach8InfoRec, pMode);
		pMode = pModeSv; 
	  } else if (pMode->HDisplay > 1024) {
		pModeSv=pMode->next;
		ErrorF("%s %s: Width to large for mode %s (max 1024)\n", 
			XCONFIG_PROBED, mach8InfoRec.name, pMode->name);
		xf86DeleteMode(&mach8InfoRec, pMode);
		pMode = pModeSv;
	  } else if (pMode->HDisplay * pMode->VDisplay > memavail) {
		pModeSv=pMode->next;
		ErrorF("%s %s: Too little memory for mode %s\n", 
			XCONFIG_PROBED, mach8InfoRec.name, pMode->name);
		xf86DeleteMode(&mach8InfoRec, pMode);
		pMode = pModeSv;
	  } else if (((tx > 0) && (pMode->HDisplay > tx)) || 
		     ((ty > 0) && (pMode->VDisplay > ty))) {
		pModeSv=pMode->next;
		ErrorF("%s %s: Resolution %dx%d too large for virtual %dx%d\n",
			XCONFIG_PROBED, mach8InfoRec.name,
			pMode->HDisplay, pMode->VDisplay, tx, ty);
		xf86DeleteMode(&mach8InfoRec, pMode);
		pMode = pModeSv;
	  } else {
		/*
		 * Successfully looked up this mode.  If pEnd isn't 
		 * initialized, set it to this mode.
		 */
		if(pEnd == (DisplayModePtr) NULL)
			pEnd = pMode;

		if (pMode->HDisplay > maxX)
		{
			maxX = pMode->HDisplay;
			pmaxX = pMode;
		}
		if (pMode->VDisplay > maxY)
		{
			maxY = pMode->VDisplay;
			pmaxY = pMode;
		}

		pMode = pMode->next;
	  }
    } while (pMode != pEnd);
  
    mach8InfoRec.virtualX = max(maxX, mach8InfoRec.virtualX);
    mach8InfoRec.virtualY = max(maxY, mach8InfoRec.virtualY);
  
    rounding = 8;
  
    if (mach8InfoRec.virtualX % rounding)
    {
        mach8InfoRec.virtualX -= mach8InfoRec.virtualX % rounding;
	ErrorF("%s %s: Virtual width rounded down to a multiple of %d (%d)\n",
	       XCONFIG_PROBED, mach8InfoRec.name, rounding,
	       mach8InfoRec.virtualX);
        if (mach8InfoRec.virtualX < maxX)
        {
            ErrorF(
		"%s: Rounded down virtual width (%d) is too small for mode %s",
                   mach8InfoRec.name, mach8InfoRec.virtualX, pmaxX->name);
            return(FALSE);
        }
        ErrorF("%s: Virtual width rounded down to a multiple of %d (%d)\n",
               mach8InfoRec.name, rounding, mach8InfoRec.virtualX);
    }

    if (mach8InfoRec.virtualX > 1024)
    {
        ErrorF("%s: Virtual width must be no greater than 1024\n",mach8InfoRec.name);
        return(FALSE);
    }
    if ( mach8InfoRec.virtualX * mach8InfoRec.virtualY > memavail)
    {
        if (mach8InfoRec.virtualX != maxX || mach8InfoRec.virtualY != maxY)
            ErrorF(
	      "%s: Too little memory to accomodate virtual size and mode %s\n",
                   mach8InfoRec.name,
                   (mach8InfoRec.virtualX == maxX) ? pmaxX->name : pmaxY->name);
        else
            ErrorF("%s: Too little memory to accomodate modes %s and %s\n",
                   mach8InfoRec.name, pmaxX->name, pmaxY->name);
        return(FALSE);
    }
    if (xf86Verbose)
        ErrorF("%s %s: Virtual resolution set to %dx%d\n",
	       OFLG_ISSET(XCONFIG_VIRTUAL,&mach8InfoRec.xconfigFlag) ?
		  XCONFIG_GIVEN : XCONFIG_PROBED, mach8InfoRec.name,
               mach8InfoRec.virtualX, mach8InfoRec.virtualY);

    return(TRUE);
}