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 1993 Harm Hanemaayer */
- /* partially copyrighted (C) 1993 by Hartmut Schirmer */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <termios.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <sys/mman.h>
-
- #include "vga.h"
- #include "libvga.h"
- #include "driver.h"
-
- /* This routine is a pain in my ass and definitely needs to be virtualized..
- M. Weller. (mach32 support) */
- void vga_waitretrace() {
- if ((__svgalib_chipset == MACH32)&&SVGAMODE(CM))
- {
- unsigned char csync;
-
- csync=inb(0xd2ee)>>3; /* Current sync polarity in bit 2,
- 0-pos, 1-neg */
- /*Wait until in displayed area..*/
- while((inb(0x2e8)^csync)&2);
- /*Wait until V_SYNC*/
- csync=~csync;
- while((inb(0x2e8)^csync)&2);
- /* Hmm, is a return missing here? -- HH */
- /* Umm.. *scratch head* Certainly.. -- MW (mach32) */
- return;
- }
- while (!(inb(0x3da) & 8));
- while (inb(0x3da) & 8);
- }
-
- static void *linearframebuffer;
-
- /*
- * The way IS_LINEAR gets indicated is rather convoluted; if the driver
- * has EXT_INFO_AVAILABLE, setlinearaddressing will enable
- * the flag in __svgalib_linearset which gets set in the modeinfo by
- * vga_getmodeinfo(). The driver must turn off the flag in
- * __svgalib_linearset if linear addressing gets disabled (e.g. when
- * setting another mode).
- *
- * For any driver, the chipset getmodeinfo flag can examine a hardware
- * register and set the IS_LINEAR flag if linear addressing is enabled.
- */
-
- unsigned char *vga_getgraphmem() {
- if (vga_getmodeinfo(__svgalib_cur_mode)->flags & IS_LINEAR)
- return linearframebuffer;
- return __svgalib_graph_mem;
- }
-
- #include <linux/kernel.h>
- #include <linux/unistd.h>
-
- int __svgalib_physmem(void)
- {
- struct sysinfo si;
- si.totalram = 0;
- syscall(__NR_sysinfo, &si);
- return si.totalram;
- }
-
- static unsigned char *map_framebuffer( unsigned address, int size ) {
- int mem_fd;
- unsigned char *fb;
- mem_fd = open("/dev/mem", O_RDWR);
- fb = valloc(size);
- return mmap(
- (caddr_t)fb,
- size,
- PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_SHARED,
- mem_fd,
- (off_t)address
- );
- close(mem_fd);
- /* Using addr 0 (kernel comes up with 0x40000000),
- and only MAP_SHARED works, but wastes 2Mb
- of memory. */
- }
-
- /*
- * This function is to be called after a SVGA graphics mode set
- * in banked mode. Probing in VGA-compatible textmode is not a good
- * idea.
- */
-
- static int verify_linear_mapping( int base, int size ) {
- unsigned char *fb;
- int i, result;
- int (*lfn)() = driverspecs->linear;
- /* Write signatures. */
- for (i = 0; i < size / 65536; i++) {
- vga_setpage(i);
- *(unsigned long *)__svgalib_graph_mem = i;
- }
- vga_setpage(0);
- /* Enable the linear mapping on the card. */
- (*lfn)(LINEAR_ENABLE, base);
- /* Let the OS map it. */
- fb = map_framebuffer(base, size);
- if ((int)fb == -1 || fb == NULL) {
- (*lfn)(LINEAR_DISABLE, base);
- result = -1;
- goto cleanupsignatures;
- }
- /* Verify framebuffer signatures. */
- for (i = 0; i < size / 65536; i++) {
- unsigned long data;
- data = *(unsigned long *)((unsigned char *)fb + i * 65536);
- if (data != i) {
- munmap((caddr_t)fb, size);
- (*lfn)(LINEAR_DISABLE, base);
- result = -1;
- #if 0
- printf("svgalib: Signature mismatch at 0x%08X (0x%08X), 0x%08X != 0x%08X.\n",
- fb + i * 65536, base + i * 65536, data, i);
- #endif
- goto cleanupsignatures;
- }
- }
- /* Linear framebuffer is OK. */
- printf("svgalib: Found linear framebuffer at 0x%08X.\n", base);
- result = 0;
- munmap((caddr_t)fb, size);
- (*lfn)(LINEAR_DISABLE, base);
- cleanupsignatures:
- /* Clean up the signatures (write zeroes). */
- for (i = 0; i < size / 65536; i++) {
- vga_setpage(i);
- *(unsigned long *)__svgalib_graph_mem = 0;
- }
- vga_setpage(0);
- return result;
- }
-
- /* cf. vga_waitretrace, M.Weller */
- int vga_setlinearaddressing() {
- int (*lfn)() = driverspecs->linear;
- int memory;
- vga_modeinfo *modeinfo;
- modeinfo = vga_getmodeinfo(__svgalib_cur_mode);
- if (modeinfo->flags & EXT_INFO_AVAILABLE)
- memory = modeinfo->memory;
- else
- memory = (modeinfo->bytesperpixel * modeinfo->maxpixels
- + 0xFFFF) & 0xFFFF0000; /* Round up 4K. */
-
- if (lfn) {
- /* 'Linear' driver function available. */
- unsigned long gran;
- unsigned long mapaddr, maxmap;
- int range;
- int i;
- /* First try the fixed bases that the driver reports. */
- i = 0;
- for (;; i++) {
- mapaddr = (*lfn)(LINEAR_QUERY_BASE, i);
- if ((int)mapaddr == -1)
- break;
- if (mapaddr <= __svgalib_physmem())
- continue;
- /* Check that the linear framebuffer is writable. */
- if (verify_linear_mapping(mapaddr, memory) != -1)
- goto foundlinearframebuffer;
- }
- /* Attempt mapping for device that maps in low memory range. */
- gran = (*lfn)(LINEAR_QUERY_GRANULARITY);
- range = (*lfn)(LINEAR_QUERY_RANGE);
- if (range == 0)
- return -1;
- /* Place it immediately after the physical memory. */
- mapaddr = (__svgalib_physmem() + (gran + gran - 1)) & ~(gran - 1);
- maxmap = (range - 1) * gran;
- if (mapaddr > maxmap) {
- puts("svgalib: Too much physical memory, cannot map aperture\n");
- return -1;
- }
- if (verify_linear_mapping(mapaddr, memory) == -1)
- return -1;
-
- foundlinearframebuffer:
- (*lfn)(LINEAR_ENABLE, mapaddr);
- linearframebuffer = map_framebuffer(mapaddr, memory);
- if ((int)linearframebuffer == -1) {
- /* Shouldn't happen. */
- (*lfn)(LINEAR_DISABLE, mapaddr);
- return -1;
- }
- __svgalib_modeinfo_linearset |= IS_LINEAR;
- return 0;
- }
-
- if( (modeinfo->flags&(CAPABLE_LINEAR|EXT_INFO_AVAILABLE)) ==
- (CAPABLE_LINEAR|EXT_INFO_AVAILABLE) ) {
- if(modeinfo->aperture_size>=modeinfo->memory) {
- __svgalib_modeinfo_linearset|=IS_LINEAR;
- linearframebuffer=modeinfo->linear_aperture;
- return 0;
- }
- }
- return -1;
- }
-
- int vga_getkey() {
- struct termio zap, original;
- char c;
- int e;
-
- ioctl(fileno(stdin), TCGETA, &original); /* Get termio */
- zap = original;
- zap.c_cc[VMIN] = 0; /* Modify termio */
- zap.c_cc[VTIME] = 0;
- zap.c_lflag = 0;
- ioctl(fileno(stdin), TCSETA, &zap); /* Set new termio */
- e = read(fileno(stdin), &c, 1); /* Read one char */
- ioctl(fileno(stdin), TCSETA, &original); /* Restore termio */
- if (e != 1)
- return 0; /* No key pressed. */
- return c; /* Return key. */
- }
-
- static void reserved_message() {
- printf("svgalib: Function not present in shared library image.\n");
- printf(" You need a newer version of svgalib.\n");
- }
-
- void vga_reserved17() {
- reserved_message();
- }
- void vga_reserved18() {
- reserved_message();
- }
- void vga_reserved19() {
- reserved_message();
- }
- void vga_reserved20() {
- reserved_message();
- }
- void vga_reserved21() {
- reserved_message();
- }
- void vga_reserved22() {
- reserved_message();
- }
-