📄 mach32.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. *//* ATI Mach32 driver (C) 1995 Michael Weller *//* eowmob@exp-math.uni-essen.de mat42b@aixrs1.hrz.uni-essen.de *//* eowmob@pollux.exp-math.uni-essen.de *//* * MICHAEL WELLER DISCLAIMS ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL MICHAEL WELLER BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *//* This tool contains one routine out of Xfree86, therefore I repeat *//* its copyright here: (Actually it is longer than the copied code) *//* * Copyright 1992 by Orest Zborowski <obz@Kodak.com> * Copyright 1993 by David Wexelblat <dwex@goblin.org> * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the names of Orest Zborowski and David Wexelblat * not be used in advertising or publicity pertaining to distribution of * the software without specific, written prior permission. Orest Zborowski * and David Wexelblat make no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. * * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. * Copyright 1993 by Kevin E. Martin, Chapel Hill, North Carolina. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Thomas Roell not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Thomas Roell makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * THOMAS ROELL, KEVIN E. MARTIN, AND RICKARD E. FAITH DISCLAIM ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE AUTHORS * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Thomas Roell, roell@informatik.tu-muenchen.de * * Rewritten for the 8514/A by Kevin E. Martin (martin@cs.unc.edu) * Modified for the Mach-8 by Rickard E. Faith (faith@cs.unc.edu) * Rewritten for the Mach32 by Kevin E. Martin (martin@cs.unc.edu) * *//* Works only if Mach32 onboard VGA is enabled. *//* Reads in eeprom. *//* There is a dirty hack in here to raise the linewidth for *//* 800x600 to 832 to keep my mem happy.. (and even though it's a *//* VRAM card... probably has to do something with mempages.... *//* I change it by tweaking the info array.. so watch out. *//* The Number of additional pixels to append is set below, it has *//* to be a multiple of 8. This seems only to be needed for 16/24bpp *//* Ok,later I found that the number of pixels has to be a multiple *//* of 64 at least... somewhere in the ATI docs, always choosing a *//* multiple of 128 was suggested.... *//* So set the multiple to be used below.. */#define PIXALIGN 64#define DAC_SAFETY 0x1d /*reminder for people with DAC!=4,3,2,0 */ /*set bits for well known DACTYPES *//* * Sync allowance in 1/1000ths. 10 (1%) corresponds to a 315 Hz * deviation at 31.5 kHz, 1 Hz at 100 Hz */#define SYNC_ALLOWANCE 10#define SUPP_32BPP /*Accept 32BPP modes *//*#define USE_RGBa *//* ifdef(SUPP_32BPP) use RGBa format (R first in memory), otherwise aBGR is used *//*Pure experimental and probably specific to my card (VRAM 68800-3) */#define MAXCLK8 2000 /*This effectly switches this off.. seems not to be needed with PIXTWEAK>32 */#define MAXCLK16 2000 /*This effectly switches this off.. seems not to be needed with PIXTWEAK>32 */#define MAXCLK24 49#define MAXCLK32 39/*Clock values to be set on original ATI Mach32 to emulate vga compatible timings *//*Bit 4 is ATI3e:4, bits 3-2 are ATI39:1-0, bits 1-0 are ATI38:7-6 */#define SVGA_CLOCK 0x09/*And here are minimum Vfifo values.. just guessed values (valid settings are 0..15): */#define VFIFO8 6#define VFIFO16 9#define VFIFO24 14#define VFIFO32 14/*Wait count for busywait loops */#define BUSYWAIT 10000000 /* Around 1-2 sec on my 486-50 this should be enough for any graphics command to complete, even on a fast machine. however after that slower code is called to ensure a minimum wait of another: */#define ADDIWAIT 5 /* seconds. *//*#define FAST_MEMCPY *//* Use a very fast inline memcpy instead of the standard libc one */ /* Seems not to make a big difference for the Mach32 */ /* Even more seems to be MUCH slower than the libc memcpy, even */ /* though this uses a function call. Probably just rep movsb is */ /* fastest. So => do not use this feature. */#define MODESWITCHDELAY 50000 /* used to wait for clocks to stabilize *//*#define DEBUG *//*#define DEBUG_KEY *//*Wait for keypress at some locations *//*#define EXPERIMENTAL *//*Experimental flags *//*#define FAKEBGR *//* Use BGR instead of RGB, this is for debugging only. Leave it alone! */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <ctype.h>#include <time.h>#include <sys/types.h>#include <sys/mman.h>#include "mach32.h"#include "8514a.h"#include "vga.h"#include "libvga.h"#include "driver.h"#define OFF_ALLOWANCE(a) ((a) * (1.0f - (SYNC_ALLOWANCE/1000.0f)))#define ADD_ALLOWANCE(a) ((a) * (1.0f + (SYNC_ALLOWANCE/1000.0f)))/*List preallocate(for internal info table mixup commands): */#define PREALLOC 16/*Internal mixup commands: */#define CMD_MSK 0xf000#define CMD_ADD 0x0000#define CMD_DEL 0x1000#define CMD_MOD 0x2000#define CMD_CPY 0x3000#define CMD_MOV 0x4000#define ATIPORT 0x1ce#define ATIOFF 0x80#define ATISEL(reg) (ATIOFF+reg)/* Ports we use: *//* moved to 8514a.h - Stephen Lee */#define VGA_DAC_MASK 0x3C6#define DISP_STATUS 0x2E8#define DAC_W_INDEX 0x02EC#define DAC_DATA 0x02ED#define DAC_MASK 0x02EA#define DAC_R_INDEX 0x02EB#define DAC0 0x02EC#define DAC1 0x02ED#define DAC2 0x02EA#define DAC3 0x02EB/* Bit masks: */#define GE_BUSY 0x0200#define ONLY_8514 1#define LOCAL_BUS_CONF2 (1<<6)#define BUS_TYPE 0x000E#define PCI 0x000E#define ISA 0x0000#define Z4GBYTE (1<<13)/* ATI-EXT regs to save (ensure lock regs are set latest, that is they are listed first here!): */static const unsigned char mach32_eregs[] ={ /* Lock regs: */ 0x38, 0x34, 0x2e, 0x2b, /* All other extended regs. */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x20, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2c, 0x2d, 0x30, 0x31, 0x32, 0x33, 0x35, 0x36, 0x37, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};/* Extended ATI VGA regs that have to be reset for plain vga-modes *//* First num is ATI reg, 2nd has bits set where to clear bits in the *//* ATI reg. Note: the most important clocksel regs 0x38 & 0x39 are *//* handled manually */static const unsigned char mach32_ati_ext[] ={ 0x05, 0x80, /* VGA std blink rate */ 0x23, 0x18, /* clear ext CRTC bits */ 0x26, 0xc1, /* no skew of disp enab, dashedunderl */ 0x27, 0xf1, 0x2c, 0x41, 0x2d, 0xff, /* several ext bits */ 0x2e, 0xef, /* ext page pointers */ 0x30, 0x65, 0x31, 0x7b, 0x32, 0xff, 0x33, 0xc0, 0x34, 0x03, 0x35, 0xf7, 0x36, 0xf7, 0x3d, 0x0d};/* Mach32 regs to save.. read, write address alternating: */static const unsigned short mach32_acc_regs[] ={ 0xB2EE, 0x06E8, /* H_DISP(ALT H_TOTAL) */ 0xC2EE, 0x12E8, /* V_TOTAL */ 0xC6EE, 0x16E8, /* V_DISP */ 0xCAEE, 0x1AE8, /* V_SYNC_STRT */ 0xD2EE, 0x1EE8, /* V_SYNC_WID */ 0x4AEE, 0x4AEE, /* CLOCK_SEL */ 0x96EE, 0x96EE, /* BRES_COUNT */ 0x86E8, 0x86E8, /* CUR_X */ 0x82E8, 0x82E8, /* CUR_Y */ 0x22EE, 0x22EE, /* DAC_CONT(PCI) */ 0xF2EE, 0xF2EE, /* DEST_COLOR_CMP_MASK */ 0x92E8, 0x92E8, /* ERR_TERM */ 0xA2EE, 0xA2EE, /* LINEDRAW_OPT */ 0x32EE, 0x32EE, /* LOCAL_CNTL */ 0x6AEE, 0x6AEE, /* MAX_WAITSTATES / MISC_CONT(PCI) */ 0x36EE, 0x36EE, /* MISC_OPTIONS */ 0x82EE, 0x82EE, /* PATT_DATA_INDEX */ 0x8EEE, 0x7AEE, /* EXT_GE_CONFIG */ 0xB6EE, 0x0AE8, /* H_SYNC_STRT */ 0xBAEE, 0x0EE8, /* H_SYNC_WID */ 0x92EE, 0x7EEE, /* MISC_CNTL */ 0xDAEE, 0x8EE8, /* SRC_X */ 0xDEEE, 0x8AE8, /* SRC_Y */ 0x52EE, 0x52EE, /* SCRATCH0 */ 0x56EE, 0x56EE, /* SCRATCH1 */ 0x42EE, 0x42EE, /* MEM_BNDRY */ 0x5EEE, 0x5EEE, /* MEM_CFG */};/* Some internal flags */#define PAGE_UNKNOWN 0#define PAGE_DIFF 1#define PAGE_BOTH 2#define DAC_MODE8 0#define DAC_MODEMUX 1#define DAC_MODE555 2#define DAC_MODE565 3#define DAC_MODERGB 4#define DAC_MODE32B 5#define DAC_SEMICLK 0x80#define EMU_POSS 1#define EMU_OVER 2#define EEPROM_USE_CHKSUM 1#define EEPROM_USE_MEMCFG 2#define EEPROM_USE_TIMING 4#define EEPROM_UPDATE 8/*DAC_MODETABLES: */static const unsigned char mach32_dac1[4] ={0x00, 0x00, 0xa2, 0xc2};static const unsigned char mach32_dac4[5] ={0x00, 0x00, 0xa8, 0xe8, 0xf8};static const unsigned char mach32_dac5[6] ={0x00, 0x00, 0x20, 0x21, 0x40,#ifdef USE_RGBa 0x61#else 0x60#endif};typedef struct { unsigned char vfifo16, vfifo24; unsigned char h_disp, h_total, h_sync_wid, h_sync_strt; unsigned short v_total, v_disp, v_sync_strt; unsigned char disp_cntl, v_sync_wid; unsigned short clock_sel, flags, mask, offset;} mode_entry;typedef enum { R_UNKNOWN, R_STANDARD, R_EXTENDED} accelstate;/*sizeof mode_entry in shorts: */#define SOMOD_SH ((sizeof(mode_entry)+sizeof(short)-1)/sizeof(short))/*I put the appropriate VFIFO values from my selfdefined modes in... raise them if you get strange screen flickering.. (but they have to be <=0xf !!!!) */static const mode_entry predef_modes[] ={ {0x9, 0xe, 0x4f, 0x63, 0x2c, 0x52, 0x418, 0x3bf, 0x3d6, 0x23, 0x22, 0x50, 0, 0x0000, 0}, {0x9, 0xe, 0x4f, 0x69, 0x25, 0x52, 0x40b, 0x3bf, 0x3d0, 0x23, 0x23, 0x24, 0, 0x0001, 7}, {0x9, 0xe, 0x63, 0x84, 0x10, 0x6e, 0x580, 0x4ab, 0x4c2, 0x33, 0x2c, 0x7c, 0, 0x003f, 8}, {0x9, 0xe, 0x63, 0x84, 0x10, 0x6d, 0x580, 0x4ab, 0x4c2, 0x33, 0x0c, 0x0c, 0, 0x003d, 8}, {0x9, 0xe, 0x63, 0x7f, 0x09, 0x66, 0x4e0, 0x4ab, 0x4b0, 0x23, 0x02, 0x0c, 0, 0x003c, 8}, {0x9, 0xe, 0x63, 0x83, 0x10, 0x68, 0x4e3, 0x4ab, 0x4b3, 0x23, 0x04, 0x30, 0, 0x0038, 8}, {0x9, 0xe, 0x63, 0x7d, 0x12, 0x64, 0x4f3, 0x4ab, 0x4c0, 0x23, 0x2c, 0x1c, 0, 0x0030, 8}, {0x9, 0xe, 0x63, 0x82, 0x0f, 0x6a, 0x531, 0x4ab, 0x4f8, 0x23, 0x06, 0x10, 0, 0x0020, 8}, {0xd, 0xe, 0x7f, 0x9d, 0x16, 0x81, 0x668, 0x5ff, 0x600, 0x33, 0x08, 0x1c, 0, 0x0001, 9}, {0xd, 0xe, 0x7f, 0xa7, 0x31, 0x82, 0x649, 0x5ff, 0x602, 0x23, 0x26, 0x3c, 0, 0x0003, 9}, {0xd, 0xe, 0x7f, 0xad, 0x16, 0x85, 0x65b, 0x5ff, 0x60b, 0x23, 0x04, 0x38, 0, 0x0013, 9}, {0xd, 0xe, 0x7f, 0xa5, 0x31, 0x83, 0x649, 0x5ff, 0x602, 0x23, 0x26, 0x38, 0, 0x0017, 9}, {0xd, 0xe, 0x7f, 0xa0, 0x31, 0x82, 0x649, 0x5ff, 0x602, 0x23, 0x26, 0x38, 0, 0x001f, 9}, {0xe, 0xe, 0x9f, 0xc7, 0x0a, 0xa9, 0x8f8, 0x7ff, 0x861, 0x33, 0x0a, 0x2c, 0, 0x0001, 10}, {0xe, 0xe, 0x9f, 0xc7, 0x0a, 0xa9, 0x838, 0x7ff, 0x811, 0x33, 0x0a, 0x2c, 0, 0x0003, 10},};#define NUM_MODES (sizeof(predef_modes)/sizeof(mode_entry))static const mode_entry **mach32_modes = NULL;static int mach32_clocks[32] ={ /* init to zero for safety */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};static signed char mach32_clock_by2[32], mach32_clock_by3[32];/*Bitmask is 1 256-col, 2 15-16 bpp, 4 24 bpp, 8 32bpp */static unsigned char mach32_mmask[2][8] ={ { /* General supported modes.. */ 3, 3, 0xf, 1, 0x7, 0xf, 1, 1}, { /* Modes above 80Mhz.. */ 0, 0, 1, 0, 0, 0xf, 0, 0}};/* Modes that ATI mentions for it's DACS.. this is for safety and the internal predefined modes.. I think the above restrictions should be enough.. However I don't want to risk the life of your DAC so.. */static unsigned char dacmo640[] ={0x3, 0x3, 0xf, 0x1, 0x7, 0xf, 0x1, 0x1};static unsigned char dacmo800[] ={0x3, 0x3, 0xf, 0x1, 0x3, 0xf, 0x1, 0x1};static unsigned char dacmo1024[] ={0x3, 0x1, 0x3, 0x1, 0x1, 0xf, 0x1, 0x1};static unsigned char dacmo1280[] ={0x0, 0x0, 0x1, 0x0, 0x0, 0xf, 0x0, 0x0};/* several globals.. mostly to record current state of the driver */static char vfifo8 = VFIFO8, vfifo16 = VFIFO16, vfifo24 = VFIFO24, vfifo32 = VFIFO32, mach32_apsiz = 0;static char dac_override = 127, svga_clock = SVGA_CLOCK, mach32_ast = 0;static char *eeprom_fname = NULL;static char emuimage = EMU_POSS | EMU_OVER; /* Never set EMU_OVER w/o EMU_POSS !!! */static char eeprom_option = EEPROM_USE_CHKSUM | EEPROM_USE_MEMCFG | EEPROM_USE_TIMING;static unsigned short *mach32_eeprom, mach32_disp_shadow = 0, mach32_strictness = 0,*mach32_modemixup;static unsigned short mach32_apadd = 1, mach32_memcfg;static unsigned short mach32_ge_pitch = 0, mach32_ge_off_h = 0, mach32_ge_off_l = 0;static unsigned short mach32_bkgd_alu_fn = 7, mach32_frgd_alu_fn = 7;static unsigned short mach32_frgd_col = 0xFFFF, mach32_bkgd_col = 0;static unsigned short mach32_polyfill = 0, mach32_rop = ROP_COPY;static int mach32_memory, mach32_dac, mach32_pagemode = PAGE_UNKNOWN, mach32_dacmode = DAC_MODE8;static int mach32_chiptype, mixup_alloc = 0, mixup_ptr = 0, clocks_set = 0, ext_settings = 0;static int mach32_maxclk8 = MAXCLK8, mach32_maxclk16 = MAXCLK16, mach32_maxclk24 = MAXCLK24;static int mach32_maxclk32 = MAXCLK32, latchopt = ~0, bladj = -1;static int pos_ext_settings = VGA_CLUT8;static int acc_supp = HAVE_BLITWAIT | HAVE_FILLBLIT | HAVE_IMAGEBLIT | HAVE_BITBLIT | HAVE_HLINELISTBLIT;static int accel_supp = ACCELFLAG_SETFGCOLOR | ACCELFLAG_SETBGCOLOR | ACCELFLAG_SETTRANSPARENCY | ACCELFLAG_SETRASTEROP | ACCELFLAG_FILLBOX | ACCELFLAG_SCREENCOPY | ACCELFLAG_DRAWLINE | ACCELFLAG_PUTIMAGE | ACCELFLAG_DRAWHLINELIST | ACCELFLAG_PUTBITMAP | ACCELFLAG_SCREENCOPYMONO | ACCELFLAG_SETMODE | ACCELFLAG_POLYLINE | ACCELFLAG_POLYHLINE | ACCELFLAG_POLYFILLMODE | ACCELFLAG_SYNC;static int palcurind = -1;static int palsetget = -1;static accelstate mach32_accelstate = R_UNKNOWN;#ifdef DEBUGstatic char verbose = 1;#elsestatic char verbose = 0;#endif#ifdef EXPERIMENTALstatic unsigned mach32_experimental = 0;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -