home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / src / gvga6400.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-11  |  6.0 KB  |  302 lines

  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. /* GVGA 6400 driver Copyright 1994 Arno Schaefer */
  11. /* only Hires 256 color modes (640x480, 800x600) supported */
  12.  
  13.  
  14. #include <stdlib.h>    /* for NULL */
  15. #include <sys/types.h>
  16. #include <sys/mman.h>
  17. #include <fcntl.h>
  18. #include <unistd.h>
  19.  
  20. #include "vga.h"
  21. #include "libvga.h"
  22. #include "driver.h"
  23.  
  24. #include "gvga6400.regs"
  25.  
  26. /* Mode table */
  27. static ModeTable gvga6400_modes[] =
  28. {
  29.         OneModeEntry (640x480x256),
  30.     OneModeEntry (800x600x256),
  31.     END_OF_MODE_TABLE
  32. };
  33.  
  34. static unsigned char last_page = 0;
  35.  
  36. static int gvga6400_setregs (const unsigned char regs[]);
  37. static int gvga6400_init (int force, int par1, int par2);
  38.  
  39. /* Fill in chipset-specific modeinfo */
  40.  
  41. static int gvga6400_getmodeinfo (int mode, vga_modeinfo *modeinfo)
  42. {
  43.     if (modeinfo->bytesperpixel == 1)    /* linear mode */
  44.     {
  45.         modeinfo->maxpixels = 512 * 1024;
  46.         modeinfo->startaddressrange = 0xffff;
  47.     }
  48.     else switch (modeinfo->colors)
  49.     {
  50.         case 16 :    /* 4-plane 16 color mode */
  51.             modeinfo->maxpixels = 65536 * 8;
  52.             modeinfo->startaddressrange = 0x7ffff;
  53.             break;
  54.         case 256 :    /* 4-plane 256 color mode */
  55.             modeinfo->maxpixels = 65536 * 4;
  56.             modeinfo->startaddressrange = 0x3ffff;
  57.             break;
  58.     }
  59.  
  60.     modeinfo->maxlogicalwidth = 2040;
  61.     modeinfo->haveblit = 0;
  62.     modeinfo->flags &= ~IS_INTERLACED;
  63.     modeinfo->flags |= HAVE_RWPAGE;
  64.  
  65.     return 0;
  66. }
  67.  
  68. static int nothing () { return 0; }
  69.  
  70. /* Return nonzero if mode available */
  71.  
  72. static int gvga6400_modeavailable (int mode)
  73. {
  74.     const unsigned char *regs;
  75.  
  76.     regs = LOOKUPMODE (gvga6400_modes, mode);
  77.  
  78.     if (regs == NULL || mode == GPLANE16)
  79.         return vga_driverspecs.modeavailable(mode);
  80.     if (regs==DISABLE_MODE || mode<=TEXT || mode>GLASTMODE)
  81.         return 0;
  82.  
  83.     return SVGADRV;
  84. }
  85.  
  86.  
  87. /* Set a mode */
  88.  
  89. static int lastmode;
  90.  
  91. static int gvga6400_setmode (int mode, int prv_mode)
  92. {
  93.     const unsigned char *regs;
  94.  
  95.     switch (gvga6400_modeavailable (mode))
  96.     {
  97.         case STDVGADRV:
  98.             return vga_driverspecs.setmode(mode, prv_mode);
  99.         case SVGADRV:
  100.             regs = LOOKUPMODE (gvga6400_modes, mode);
  101.             if (regs != NULL) break;
  102.         default:
  103.             return (1);    /* not available */
  104.     }
  105.  
  106.     __vga_setregs (regs);
  107.     gvga6400_setregs (regs);
  108.  
  109.     return 0;
  110. }
  111.  
  112. static void gvga6400_setpage (int page)
  113. {
  114.     page &= 7;
  115.     last_page = 0x40 | page | (page << 3);
  116.  
  117.     outb (0x3c4, 6);
  118.     outb (0x3c5, last_page);
  119. }
  120.  
  121. static void gvga6400_setrdpage (int page)
  122. {
  123.     last_page &= 0xf8;
  124.     last_page |= page & 0x07;
  125.  
  126.     outb (0x3c4, 6);
  127.     outb (0x3c5, last_page);
  128. }
  129.  
  130. static void gvga6400_setwrpage (int page)
  131. {
  132.     last_page &= 0xc7;
  133.     last_page |= ((page & 7) << 3);
  134.  
  135.     outb (0x3c4, 6);
  136.     outb (0x3c5, last_page);
  137. }
  138.  
  139.  
  140. /* Set display start */
  141.  
  142. static int gvga6400_setdisplaystart (int address)
  143. {
  144.     vga_modeinfo modeinfo;
  145.     gvga6400_getmodeinfo (lastmode, &modeinfo);
  146.  
  147.     if (modeinfo.bytesperpixel == 0) switch (modeinfo.colors)
  148.     {
  149.         case 16 :    /* planar 16-color mode */
  150.             inb (0x3da);
  151.             outb (0x3c0, 0x13 + 0x20);
  152.             outb (0x3c0, (inb (0x3c1) & 0xf0) | (address & 7));
  153.                 /* write sa0-2 to bits 0-2 */
  154.             address >>= 3;
  155.             break;
  156.         case 256 :    /* planar 256-color mode */
  157.             inb (0x3da);
  158.             outb (0x3c0, 0x13 + 0x20);
  159.             outb (0x3c0, (inb (0x3c1) & 0xf0) | ((address & 3) << 1));
  160.                 /* write sa0-1 to bits 1-2 */
  161.             address >>= 2;
  162.             break;
  163.     }
  164.  
  165.     outw (0x3d4, 0x0d + (address & 0x00ff) * 256);        /* sa0-sa7 */
  166.     outw (0x3d4, 0x0c + (address & 0xff00));        /* sa8-sa15 */
  167.  
  168.     return 0;
  169. }
  170.  
  171. static int gvga6400_setlogicalwidth (int width)
  172. {
  173.     outw (0x3d4, 0x13 + (width >> 3) * 256);    /* lw3-lw11 */
  174.     return 0;
  175. }
  176.  
  177.  
  178. static int gvga6400_test ()
  179. {
  180.     int mem_fd;
  181.     unsigned char *vga_bios;
  182.     int result = 0;
  183.     int address;
  184.  
  185.     mem_fd = open("/dev/mem", O_RDONLY);
  186.  
  187.     /* Changed to use valloc(). */
  188.     if ((vga_bios = valloc(4096)) == NULL)
  189.     {
  190.         fprintf (stderr, "svgalib: malloc error\n");
  191.         exit (-1);
  192.     }
  193.  
  194.     vga_bios = (unsigned char *) mmap 
  195.     (
  196.         (caddr_t) vga_bios,
  197.         4096,
  198.         PROT_READ,
  199.         MAP_SHARED | MAP_FIXED,
  200.         mem_fd,    
  201.         0xc0000
  202.     );
  203.  
  204.     if ((long) vga_bios < 0)
  205.     {
  206.         fprintf (stderr, "svgalib: mmap error\n");
  207.         exit (-1);
  208.     }
  209.  
  210.     address = vga_bios[0x37];
  211.  
  212.     if (vga_bios[address] == 0x77 &&
  213.     vga_bios[address + 1] == 0x11 &&
  214.     vga_bios[address + 2] == 0x99 &&
  215.     vga_bios[address + 3] == 0x66)
  216.     {
  217.         result = 1;
  218.         gvga6400_init (0,0,0);
  219.     }
  220.  
  221. #if 0
  222.     munmap ((caddr_t) vga_bios, 4096);
  223.     free (vga_bios);
  224. #endif
  225.     close(mem_fd);
  226.  
  227.     return (result);
  228. }
  229.  
  230. static int gvga6400_saveregs (unsigned char regs[])
  231. {
  232.     outb (0x3c4, 6);
  233.     regs[EXT+2] = inb (0x3c5);
  234.     outb (0x3c4, 7);
  235.     regs[EXT+3] = inb (0x3c5);
  236.     outb (0x3c4, 8);
  237.     regs[EXT+4] = inb (0x3c5);
  238.     outb (0x3c4, 0x10);
  239.     regs[EXT+5] = inb (0x3c5);
  240.     outb (0x3ce, 9);
  241.     regs[EXT+6] = inb (0x3cf);
  242.     outb (0x3d4, 0x2f);
  243.     regs[EXT+10] = inb (0x3d5);
  244.  
  245.     return (11);
  246. }
  247.  
  248. static int gvga6400_setregs (const unsigned char regs[])
  249. {
  250.     outb (0x3c4, 6);
  251.     outb (0x3c5, regs[EXT+2]);
  252.     outb (0x3c4, 7);
  253.     outb (0x3c5, regs[EXT+3]);
  254.     outb (0x3c4, 8);
  255.     outb (0x3c5, regs[EXT+4]);
  256.     outb (0x3c4, 0x10);
  257.     outb (0x3c5, regs[EXT+5]);
  258.     outb (0x3ce, 9);
  259.     outb (0x3cf, regs[EXT+6]);
  260.     outb (0x3d4, 0x2f);
  261.     outb (0x3d5, regs[EXT+10]);
  262.  
  263.     return (0);
  264. }
  265.  
  266. DriverSpecs gvga6400_driverspecs = {
  267.     gvga6400_saveregs,
  268.     gvga6400_setregs,
  269.     nothing,
  270.     nothing,
  271.     gvga6400_test,
  272.     gvga6400_init,
  273.     (int (*) ()) gvga6400_setpage,
  274.     (int (*) ()) gvga6400_setrdpage,
  275.     (int (*) ()) gvga6400_setwrpage,
  276.     gvga6400_setmode,
  277.     gvga6400_modeavailable,
  278.     gvga6400_setdisplaystart,
  279.     gvga6400_setlogicalwidth,
  280.     gvga6400_getmodeinfo,
  281.     0,    /* bitblt */
  282.     0,    /* imageblt */
  283.     0,    /* fillblt */
  284.     0,    /* hlinelistblt */
  285.     0,    /* bltwait */
  286.     0,    /* extset */
  287.     0,
  288.     0,    /* linear */
  289.     NULL    /* accelspecs */
  290. }; 
  291.  
  292. /* Initialize chipset (called after detection) */
  293.  
  294. static int gvga6400_init (int force, int par1, int par2)
  295. {
  296.     if (__svgalib_driver_report)
  297.         printf ("Using Genoa GVGA 6400 driver.\n");
  298.     driverspecs = &gvga6400_driverspecs;
  299.  
  300.     return 0;
  301. }
  302.