📄 ati.c
字号:
/* 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. */#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"#include "vgaregs.h"#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 6#define ATIREG(s) (EXT+(s)-0xa0)#define ATI_TOTAL_REGS (VGA_TOTAL_REGS + 0xbf - 0xa0)#define MIN(a,b) (((a)<(b))?(a):(b))#define ABS(a) (((a)<0)?(-(a)):(a))#define ATIGETEXT(index) (outb(ati_base, (index)), inb(1 + ati_base))#define ATISETEXT(index, value) outw(ati_base, ((value) << 8 | (index)))static unsigned char ati_flags_42, ati_flags_44;static int ati_chiptype;static int ati_memory;static short ati_base = 0;static char *ati_name[] ={"unknown", "18800", "18800-1", "28800-2", "28800-4", "28800-5", "68800"};static void nothing(void){}/* Initialize chipset (called after detection) */static int ati_init(int force, int par1, int par2){ __svgalib_driverspecs = &__svgalib_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); } /* * Find out how much video memory the VGA Wonder side thinks it has. */ if (ati_chiptype < ATI_28800_2) { if (ATIGETEXT(0xbb) & 0x20) ati_memory = 512; else ati_memory = 256; } else { unsigned char b = ATIGETEXT(0xB0); if (b & 0x08) ati_memory = 1024; else if (b & 0x10) ati_memory = 512; else ati_memory = 256; } if (__svgalib_driver_report) printf("Using ATI (mostly VGA) driver, (%s, %dK).\n", ati_name[ati_chiptype], ati_memory); __svgalib_banked_mem_base=0xa0000; __svgalib_banked_mem_size=0x10000; return 1;}/* Read and store chipset-specific registers */static int ati_saveregs(unsigned char regs[]){ regs[ATIREG(0xb2)] = ATIGETEXT(0xb2); if (ati_chiptype > ATI_18800) { regs[ATIREG(0xbe)] = ATIGETEXT(0xbe); if (ati_chiptype >= ATI_28800_2) { regs[ATIREG(0xbf)] = ATIGETEXT(0xbf); regs[ATIREG(0xa3)] = ATIGETEXT(0xa3); regs[ATIREG(0xa6)] = ATIGETEXT(0xa6); regs[ATIREG(0xa7)] = ATIGETEXT(0xa7); regs[ATIREG(0xab)] = ATIGETEXT(0xab); regs[ATIREG(0xac)] = ATIGETEXT(0xac); regs[ATIREG(0xad)] = ATIGETEXT(0xad); regs[ATIREG(0xae)] = ATIGETEXT(0xae); } } regs[ATIREG(0xb0)] = ATIGETEXT(0xb0); regs[ATIREG(0xb1)] = ATIGETEXT(0xb1); regs[ATIREG(0xb3)] = ATIGETEXT(0xb3); regs[ATIREG(0xb5)] = ATIGETEXT(0xb5); regs[ATIREG(0xb6)] = ATIGETEXT(0xb6); regs[ATIREG(0xb8)] = ATIGETEXT(0xb8); regs[ATIREG(0xb9)] = ATIGETEXT(0xb9); regs[ATIREG(0xba)] = ATIGETEXT(0xba); regs[ATIREG(0xbd)] = ATIGETEXT(0xbd); return ATI_TOTAL_REGS - VGA_TOTAL_REGS;}/* Set chipset-specific registers */static void ati_setregs(const unsigned char regs[], int mode){ ATISETEXT(0xb2, regs[ATIREG(0xb2)]); if (ati_chiptype > ATI_18800) { ATISETEXT(0xbe, regs[ATIREG(0xbe)]); if (ati_chiptype >= ATI_28800_2) { ATISETEXT(0xbf, regs[ATIREG(0xbf)]); ATISETEXT(0xa3, regs[ATIREG(0xa3)]); ATISETEXT(0xa6, regs[ATIREG(0xa6)]); ATISETEXT(0xa7, regs[ATIREG(0xa7)]); ATISETEXT(0xab, regs[ATIREG(0xab)]); ATISETEXT(0xac, regs[ATIREG(0xac)]); ATISETEXT(0xad, regs[ATIREG(0xad)]); ATISETEXT(0xae, regs[ATIREG(0xae)]); } } ATISETEXT(0xb0, regs[ATIREG(0xb0)]); ATISETEXT(0xb1, regs[ATIREG(0xb1)]); ATISETEXT(0xb3, regs[ATIREG(0xb3)]); ATISETEXT(0xb5, regs[ATIREG(0xb5)]); ATISETEXT(0xb6, regs[ATIREG(0xb6)]); ATISETEXT(0xb8, regs[ATIREG(0xb8)]); ATISETEXT(0xb9, regs[ATIREG(0xb9)]); ATISETEXT(0xba, regs[ATIREG(0xba)]); ATISETEXT(0xbd, regs[ATIREG(0xbd)]);}/* Fill in chipset specific mode information */static void ati_getmodeinfo(int mode, vga_modeinfo * modeinfo){ __svgalib_vga_driverspecs.getmodeinfo(mode, modeinfo);}/* Return non-zero if mode is available */static int ati_modeavailable(int mode){ return __svgalib_vga_driverspecs.modeavailable(mode);}/* Set a mode */static int ati_setmode(int mode, int prv_mode){ unsigned char regs[ATI_TOTAL_REGS]; if (mode != TEXT) { /* Mess with the timings before passing it off to the vga driver */ ati_saveregs(regs); regs[ATIREG(0xb8)] |= 0x40; regs[ATIREG(0xbe)] |= 0x10; ati_setregs(regs, mode); } return __svgalib_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(void){ 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(void){ 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_chiptype = ATI_18800; break; case '2': ati_chiptype = ATI_18800_1; break; case '3': ati_chiptype = ATI_28800_2; break; case '4': ati_chiptype = ATI_28800_4; break; case '5': ati_chiptype = ATI_28800_5; break; case 'a': ati_chiptype = ATI_68800; /* Mach 32, should someone else handle this ? * * * * On Mach32 we come here only if chipset ATI * * was EXPLICITLY set (what we support) - MW */ break; default: ati_chiptype = 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);}#if 0/* Set 64k bank (r/w) number */static void ati_setpage(int bank){ unsigned char b, mask; mask = (ati_chiptype > ATI_18800_1) ? 0x0f : 0x07; b = ((bank & mask) << 4) | (bank & mask); ATISETEXT(0xb2, b);}static void ati_setrdpage(int bank){}static void ati_setwrpage(int bank){}#endif/* Set display start */static void ati_setdisplaystart(int address){#if 0 unsigned char b; b = ((address >> 10) & ~0x3f) | (ATIGETEXT(0xb0) & 0x3f); ATISETEXT(0xb0, b);#endif __svgalib_vga_driverspecs.setdisplaystart(address);}/* Set logical scanline length (usually multiple of 8) */static void ati_setlogicalwidth(int width){ __svgalib_vga_driverspecs.setlogicalwidth(width);}/* Function table (exported) */DriverSpecs __svgalib_ati_driverspecs ={ ati_saveregs, ati_setregs, nothing, /* unlock */ nothing, /* lock */ ati_test, ati_init, (void (*)(int)) nothing, /* __svgalib_setpage */ (void (*)(int)) nothing, /* __svgalib_setrdpage */ (void (*)(int)) nothing, /* __svgalib_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 */ NULL, /* Emulation */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -