📄 mx.c
字号:
/*MX 86251 driverchipset MX 0 1 # 86251 chipset MX 0 0 # 86250 - not tested.Unless I make sure I lock after every unlock, after the firstrun, et4000 autodetects.This slows down the bank switching and setting display start.Fixes should be made either to vga.c (to run chipset_lock when entering text mode) or to the et4000 autodetection. */#include <stdlib.h>#include <stdio.h> /* for printf */#include <string.h> /* for memset */#include <unistd.h>#include "vga.h"#include "libvga.h"#include "driver.h"/* New style driver interface. */#include "timing.h"#include "vgaregs.h"#include "interface.h"#include "accel.h"#include "vgapci.h"#define MXREG_SAVE(i) (VGA_TOTAL_REGS+i)#define MX_TOTAL_REGS (VGA_TOTAL_REGS + 23)static int mx_init(int, int, int);static void mx_unlock(void);static void mx_lock(void);void __svgalib_mxaccel_init(AccelSpecs * accelspecs, int bpp, int width_in_pixels);static int mx_memory,mx_chiptype;static int mx_is_linear, mx_linear_base;static int SysControl, BankIdx;static CardSpecs *cardspecs;enum { MX86250 = 0, MX86251};static void mx_setpage(int page){ __svgalib_outCR(BankIdx,page);}static int __svgalib_mx_inlinearmode(void){return mx_is_linear;}/* Fill in chipset specific mode information */static void mx_getmodeinfo(int mode, vga_modeinfo *modeinfo){ if(modeinfo->colors==16)return; modeinfo->maxpixels = mx_memory*1024/modeinfo->bytesperpixel; modeinfo->maxlogicalwidth = 4088; modeinfo->startaddressrange = mx_memory * 1024 - 1; modeinfo->haveblit = 0; modeinfo->flags &= ~HAVE_RWPAGE; if (modeinfo->bytesperpixel >= 1) { if(mx_linear_base)modeinfo->flags |= CAPABLE_LINEAR; if (__svgalib_mx_inlinearmode()) modeinfo->flags |= IS_LINEAR; }}/* Read and save chipset-specific registers */static int mx_saveregs(unsigned char regs[]){ int i; mx_unlock(); /* May be locked again by other programs (e.g. X) */ regs[MXREG_SAVE(0)] = __svgalib_inCR(0x21); regs[MXREG_SAVE(1)] = __svgalib_inCR(0x22); regs[MXREG_SAVE(2)] = __svgalib_inCR(0x23); regs[MXREG_SAVE(3)] = __svgalib_inCR(0x24); regs[MXREG_SAVE(4)] = __svgalib_inSR(0x18); regs[MXREG_SAVE(5)] = __svgalib_inSR(0x19); regs[MXREG_SAVE(6)] = __svgalib_inSR(0x1D); regs[MXREG_SAVE(7)] = __svgalib_inCR(SysControl); regs[MXREG_SAVE(21)] = __svgalib_inSR(0x11); regs[MXREG_SAVE(22)] = __svgalib_inCR(0x66); switch(mx_chiptype){ case MX86250: for(i=0x33;i<0x3d;i++)regs[MXREG_SAVE(i-0x33+8)]=__svgalib_inCR(i); break; case MX86251: regs[MXREG_SAVE(8)]=__svgalib_inCR(0x1f); regs[MXREG_SAVE(9)]=__svgalib_inCR(0x20); break; } return MX_TOTAL_REGS - VGA_TOTAL_REGS;}/* Set chipset-specific registers */static void mx_setregs(const unsigned char regs[], int mode){ int i; mx_unlock(); /* May be locked again by other programs (eg. X) */ __svgalib_outSR(0,1); __svgalib_outCR(0x21,regs[MXREG_SAVE(0)]); __svgalib_outCR(0x22,regs[MXREG_SAVE(1)]); __svgalib_outCR(0x23,regs[MXREG_SAVE(2)]); __svgalib_outCR(0x24,regs[MXREG_SAVE(3)]); __svgalib_outCR(SysControl,regs[MXREG_SAVE(7)]); __svgalib_outSR(0x1D,regs[MXREG_SAVE(6)]); __svgalib_outSR(0x18,regs[MXREG_SAVE(4)]); __svgalib_outSR(0x19,regs[MXREG_SAVE(5)]); __svgalib_outSR(0x11,regs[MXREG_SAVE(21)]); __svgalib_outCR(0x66,regs[MXREG_SAVE(22)]); __svgalib_outSR(0x1c,0x10); __svgalib_outSR(0x1c,0x00); switch(mx_chiptype){ case MX86250: for(i=0x33;i<0x3d;i++)__svgalib_outCR(i,regs[MXREG_SAVE(i-0x33+8)]); break; case MX86251: for(i=0x1f;i<0x21;i++)__svgalib_outCR(i,regs[MXREG_SAVE(i-0x1f+8)]); break; } __svgalib_outSR(0,3);}/* Return nonzero if mode is available */static int mx_modeavailable(int mode){ struct info *info; ModeTiming *modetiming; ModeInfo *modeinfo; if ((mode < G640x480x256 ) || mode == G720x348x2) return __svgalib_vga_driverspecs.modeavailable(mode); info = &__svgalib_infotable[mode]; if (mx_memory * 1024 < info->ydim * info->xbytes) return 0; modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode); modetiming = malloc(sizeof(ModeTiming)); if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) { free(modetiming); free(modeinfo); return 0; } free(modetiming); free(modeinfo); return SVGADRV;}static unsigned comp_lmn(unsigned clock) ;/* Set a mode *//* Local, called by mx_setmode(). */static void mx_initializemode(unsigned char *moderegs, ModeTiming * modetiming, ModeInfo * modeinfo, int mode){ /* long k; */ int tmp, tmptot, tmpss, tmpse, tmpbs, tmpbe, k; int offset; mx_saveregs(moderegs); moderegs[MXREG_SAVE(22)]&=0xfe; /* disable hardware cursor */ __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo); offset = modeinfo->lineWidth >> 3; moderegs[0x13] = offset&0xff; moderegs[0x14]=0x40; moderegs[0x17]=0xA3; moderegs[MXREG_SAVE(0)] = 0x00; tmp = (modetiming->CrtcHDisplay >> 3) - 1; tmptot = (modetiming->CrtcHTotal >> 3) - 5; tmpss = (modetiming->CrtcHSyncStart >> 3); tmpse = (modetiming->CrtcHSyncEnd >> 3); tmpbs = (modetiming->CrtcHSyncStart >> 3) - 1; tmpbe = (modetiming->CrtcHSyncEnd >> 3); moderegs[MXREG_SAVE(1)]=((tmptot & 0x100)>>8) | ((tmp & 0x100)>>7) | ((tmpss & 0x100)>>6) | ((tmpbs & 0x100)>>5) | ((tmpse & 0x20)>>1) | ((tmpbe & 0x40)); tmp = modetiming->CrtcVDisplay - 1; tmptot = modetiming->CrtcVTotal - 2; tmpss = modetiming->CrtcVSyncStart; tmpse = modetiming->CrtcVSyncEnd; tmpbs = modetiming->CrtcVSyncStart - 1; tmpbe = offset; /* borrow for offset */ moderegs[MXREG_SAVE(2)]=((tmptot & 0x400)>>10) | ((tmp & 0x400)>>9) | ((tmpss & 0x400)>>8) | ((tmpbs & 0x400)>>7) | ((tmpse & 0x10)<<1) | ((tmpbe & 0x300)>>2); moderegs[MXREG_SAVE(3)] = 0x60 ; if (modetiming->flags & INTERLACED) moderegs[MXREG_SAVE(3)] |= 0x8; switch (modeinfo->bitsPerPixel) { case 8: moderegs[MXREG_SAVE(3)] |= 0x3; moderegs[MXREG_SAVE(21)]=0x0; break; case 15: case 16: if(modeinfo->greenWeight==5){ moderegs[MXREG_SAVE(21)]=0x20; moderegs[MXREG_SAVE(3)] |= 0x7;} else { moderegs[MXREG_SAVE(3)] |= 0x4; moderegs[MXREG_SAVE(21)]=0x40;}; break; case 24: moderegs[MXREG_SAVE(3)] |= 0x5; moderegs[MXREG_SAVE(21)]=0x60; break; case 32: moderegs[MXREG_SAVE(3)] |= 0x6; moderegs[MXREG_SAVE(21)]=0x60; break; default: moderegs[MXREG_SAVE(3)] |= 0x3; moderegs[MXREG_SAVE(21)]=0x20; break; } if(modeinfo->bitsPerPixel!=8){ moderegs[0x28]&=0xbf; }; moderegs[MXREG_SAVE(7)] = 0x77; k=comp_lmn(modetiming->pixelClock); moderegs[MXREG_SAVE(4)] = k&0xff; moderegs[MXREG_SAVE(5)] = k>>8; moderegs[MXREG_SAVE(6)] = 0x2f; if (mx_chiptype == MX86251) { moderegs[MXREG_SAVE(8)] = offset & 0xFF; moderegs[MXREG_SAVE(9)] = (offset >> 8) | 0x50; } else if (mx_chiptype == MX86250) { moderegs[MXREG_SAVE(8)] = 0x1f; moderegs[MXREG_SAVE(9)] = 0xf7; moderegs[MXREG_SAVE(10)] = 0x77; moderegs[MXREG_SAVE(11)] = 0x1e; moderegs[MXREG_SAVE(12)] = 0x01; moderegs[MXREG_SAVE(13)] = 0x1e; moderegs[MXREG_SAVE(14)] = 0x5d; moderegs[MXREG_SAVE(15)] = 0x00; tmp = (modeinfo->bitsPerPixel + 7) >> 3; if (mx_memory == 1024) { tmp = (modetiming->CrtcHDisplay * tmp) >> 2; moderegs[MXREG_SAVE(16)] = tmp & 0x00ff;/* moderegs[MXREG_SAVE(17)] = (tmp & 0x0300);*/ } else { tmp = (modetiming->CrtcHDisplay * tmp) >> 3; moderegs[MXREG_SAVE(16)] = tmp & 0x00ff;/* moderegs[MXREG_SAVE(17)] = tmp & 0x0300;*/ } }{ int p,q,r;p=moderegs[1]+((moderegs[MXREG_SAVE(1)]&2)<<7);moderegs[2]=p&0xff;/*moderegs[MXREG_SAVE(1)]&=0xfd;moderegs[MXREG_SAVE(1)]|=(p&0x100)>>7;*/q=moderegs[4]+((moderegs[MXREG_SAVE(1)]&8)<<5);r=moderegs[0]+4;moderegs[3]&=0xe0;moderegs[3]|=(r&0x1f);moderegs[5]&=0x7f;moderegs[5]|=(r&0x20)<<2;p=moderegs[0x12]+((moderegs[0x7]&2)<<7)+((moderegs[7]&0x40)<<3)+((moderegs[MXREG_SAVE(2)]&2)<<9);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -