home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / src / vgamisc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-11  |  6.7 KB  |  258 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. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <termios.h>
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. #include <sys/ioctl.h>
  16. #include <sys/mman.h>
  17.  
  18. #include "vga.h"
  19. #include "libvga.h"
  20. #include "driver.h"
  21.  
  22. /* This routine is a pain in my ass and definitely needs to be virtualized..
  23.    M. Weller. (mach32 support) */
  24. void vga_waitretrace() {
  25.     if ((__svgalib_chipset == MACH32)&&SVGAMODE(CM))
  26.         {
  27.         unsigned char csync;
  28.  
  29.         csync=inb(0xd2ee)>>3;    /* Current sync polarity in bit 2,
  30.                        0-pos, 1-neg  */
  31.         /*Wait until in displayed area..*/
  32.         while((inb(0x2e8)^csync)&2);
  33.         /*Wait until V_SYNC*/
  34.         csync=~csync;
  35.         while((inb(0x2e8)^csync)&2);
  36.         /* Hmm, is a return missing here? -- HH */
  37.         /* Umm.. *scratch head* Certainly.. -- MW (mach32) */
  38.         return;
  39.         }
  40.     while (!(inb(0x3da) & 8));
  41.     while (inb(0x3da) & 8);
  42. }
  43.  
  44. static void *linearframebuffer;
  45.  
  46. /*
  47.  * The way IS_LINEAR gets indicated is rather convoluted; if the driver
  48.  * has EXT_INFO_AVAILABLE, setlinearaddressing will enable
  49.  * the flag in __svgalib_linearset which gets set in the modeinfo by
  50.  * vga_getmodeinfo(). The driver must turn off the flag in
  51.  * __svgalib_linearset if linear addressing gets disabled (e.g. when
  52.  * setting another mode).
  53.  * 
  54.  * For any driver, the chipset getmodeinfo flag can examine a hardware
  55.  * register and set the IS_LINEAR flag if linear addressing is enabled.
  56.  */
  57.  
  58. unsigned char *vga_getgraphmem() {
  59.     if (vga_getmodeinfo(__svgalib_cur_mode)->flags & IS_LINEAR)
  60.         return linearframebuffer;
  61.     return __svgalib_graph_mem;
  62. }
  63.  
  64. #include <linux/kernel.h>
  65. #include <linux/unistd.h>
  66.  
  67. int __svgalib_physmem(void)
  68. {
  69.     struct sysinfo si;
  70.     si.totalram = 0;
  71.     syscall(__NR_sysinfo, &si);
  72.     return si.totalram;
  73. }
  74.  
  75. static unsigned char *map_framebuffer( unsigned address, int size ) {
  76.     int mem_fd;
  77.     unsigned char *fb;
  78.     mem_fd = open("/dev/mem", O_RDWR);
  79.     fb = valloc(size);
  80.     return mmap(
  81.         (caddr_t)fb,
  82.         size,
  83.         PROT_READ | PROT_WRITE,
  84.         MAP_FIXED | MAP_SHARED,
  85.         mem_fd,
  86.         (off_t)address
  87.     );
  88.     close(mem_fd);
  89.     /* Using addr 0 (kernel comes up with 0x40000000), 
  90.         and only MAP_SHARED works, but wastes 2Mb 
  91.         of memory. */
  92. }
  93.  
  94. /*
  95.  * This function is to be called after a SVGA graphics mode set
  96.  * in banked mode. Probing in VGA-compatible textmode is not a good
  97.  * idea.
  98.  */
  99.  
  100. static int verify_linear_mapping( int base, int size ) {
  101.     unsigned char *fb;
  102.     int i, result;
  103.     int (*lfn)() = driverspecs->linear;
  104.     /* Write signatures. */
  105.     for (i = 0; i < size / 65536; i++) {
  106.         vga_setpage(i);
  107.         *(unsigned long *)__svgalib_graph_mem = i;
  108.     }
  109.     vga_setpage(0);
  110.     /* Enable the linear mapping on the card. */
  111.     (*lfn)(LINEAR_ENABLE, base);
  112.     /* Let the OS map it. */
  113.     fb = map_framebuffer(base, size);
  114.     if ((int)fb == -1 || fb == NULL) {
  115.         (*lfn)(LINEAR_DISABLE, base);
  116.         result = -1;
  117.         goto cleanupsignatures;
  118.     }
  119.     /* Verify framebuffer signatures. */
  120.     for (i = 0; i < size / 65536; i++) {
  121.         unsigned long data;
  122.         data = *(unsigned long *)((unsigned char *)fb + i * 65536);
  123.         if (data != i) {
  124.             munmap((caddr_t)fb, size);
  125.             (*lfn)(LINEAR_DISABLE, base);
  126.             result = -1;
  127. #if 0
  128.             printf("svgalib: Signature mismatch at 0x%08X (0x%08X), 0x%08X != 0x%08X.\n",
  129.                 fb + i * 65536, base + i * 65536, data, i);
  130. #endif
  131.             goto cleanupsignatures;
  132.         }
  133.     }
  134.     /* Linear framebuffer is OK. */
  135.     printf("svgalib: Found linear framebuffer at 0x%08X.\n", base);
  136.     result = 0;
  137.     munmap((caddr_t)fb, size);
  138.     (*lfn)(LINEAR_DISABLE, base);
  139. cleanupsignatures:
  140.     /* Clean up the signatures (write zeroes). */
  141.     for (i = 0; i < size / 65536; i++) {
  142.         vga_setpage(i);
  143.         *(unsigned long *)__svgalib_graph_mem = 0;
  144.     }
  145.     vga_setpage(0);
  146.     return result;
  147. }
  148.  
  149. /* cf. vga_waitretrace, M.Weller */
  150. int vga_setlinearaddressing() {
  151.     int (*lfn)() = driverspecs->linear;
  152.     int memory;
  153.     vga_modeinfo *modeinfo;
  154.     modeinfo = vga_getmodeinfo(__svgalib_cur_mode);
  155.     if (modeinfo->flags & EXT_INFO_AVAILABLE)
  156.         memory = modeinfo->memory;
  157.     else
  158.         memory = (modeinfo->bytesperpixel * modeinfo->maxpixels
  159.             + 0xFFFF) & 0xFFFF0000;        /* Round up 4K. */
  160.  
  161.     if (lfn) {
  162.         /* 'Linear' driver function available. */
  163.         unsigned long gran;
  164.         unsigned long mapaddr, maxmap;
  165.         int range;
  166.         int i;
  167.         /* First try the fixed bases that the driver reports. */
  168.         i = 0;
  169.         for (;; i++) {
  170.             mapaddr = (*lfn)(LINEAR_QUERY_BASE, i);
  171.             if ((int)mapaddr == -1)
  172.                 break;
  173.             if (mapaddr <= __svgalib_physmem())
  174.                 continue;
  175.             /* Check that the linear framebuffer is writable. */
  176.             if (verify_linear_mapping(mapaddr, memory) != -1)
  177.                 goto foundlinearframebuffer;
  178.         }
  179.         /* Attempt mapping for device that maps in low memory range. */
  180.         gran = (*lfn)(LINEAR_QUERY_GRANULARITY);
  181.         range = (*lfn)(LINEAR_QUERY_RANGE);
  182.         if (range == 0)
  183.             return -1;
  184.         /* Place it immediately after the physical memory. */
  185.         mapaddr = (__svgalib_physmem() + (gran + gran - 1)) & ~(gran - 1);
  186.         maxmap = (range - 1) * gran;
  187.         if (mapaddr > maxmap) {
  188.             puts("svgalib: Too much physical memory, cannot map aperture\n");
  189.             return -1;
  190.         }
  191.         if (verify_linear_mapping(mapaddr, memory) == -1)
  192.             return -1;
  193.  
  194. foundlinearframebuffer:
  195.         (*lfn)(LINEAR_ENABLE, mapaddr);
  196.         linearframebuffer = map_framebuffer(mapaddr, memory);
  197.         if ((int)linearframebuffer == -1) {
  198.             /* Shouldn't happen. */
  199.             (*lfn)(LINEAR_DISABLE, mapaddr);
  200.             return -1;
  201.         }
  202.         __svgalib_modeinfo_linearset |= IS_LINEAR;
  203.         return 0;
  204.     }
  205.  
  206.     if( (modeinfo->flags&(CAPABLE_LINEAR|EXT_INFO_AVAILABLE)) ==
  207.          (CAPABLE_LINEAR|EXT_INFO_AVAILABLE) ) {
  208.             if(modeinfo->aperture_size>=modeinfo->memory) {
  209.                 __svgalib_modeinfo_linearset|=IS_LINEAR;
  210.                 linearframebuffer=modeinfo->linear_aperture;
  211.                 return 0;
  212.             }
  213.     }
  214.     return -1;
  215. }
  216.  
  217. int vga_getkey() {
  218.     struct termio zap, original;
  219.     char c;
  220.     int e;
  221.  
  222.     ioctl(fileno(stdin), TCGETA, &original);    /* Get termio */
  223.     zap = original;
  224.     zap.c_cc[VMIN] = 0;                /* Modify termio  */
  225.     zap.c_cc[VTIME] = 0;
  226.     zap.c_lflag = 0;
  227.     ioctl(fileno(stdin), TCSETA, &zap);        /* Set new termio */
  228.     e = read(fileno(stdin), &c, 1);            /* Read one char */
  229.     ioctl(fileno(stdin), TCSETA, &original);    /* Restore termio */
  230.     if (e != 1)
  231.         return 0;                /* No key pressed. */
  232.     return c;                    /* Return key. */
  233. }
  234.  
  235. static void reserved_message() {
  236.     printf("svgalib: Function not present in shared library image.\n");
  237.     printf("         You need a newer version of svgalib.\n");
  238. }
  239.  
  240. void vga_reserved17() {
  241.     reserved_message();
  242. }
  243. void vga_reserved18() {
  244.     reserved_message();
  245. }
  246. void vga_reserved19() {
  247.     reserved_message();
  248. }
  249. void vga_reserved20() {
  250.     reserved_message();
  251. }
  252. void vga_reserved21() {
  253.     reserved_message();
  254. }
  255. void vga_reserved22() {
  256.     reserved_message();
  257. }
  258.