📄 chips.c
字号:
lcdHRetraceStart = __svgalib_ctSize.HRetraceStart; lcdHRetraceEnd = __svgalib_ctSize.HRetraceEnd; if (modeinfo->bitsPerPixel == 16) { lcdHRetraceStart <<= 1; lcdHRetraceEnd <<= 1; lcdHTotal <<= 1; } else if (modeinfo->bitsPerPixel == 24) { lcdHRetraceStart += (lcdHRetraceStart << 1); lcdHRetraceEnd += (lcdHRetraceEnd << 1); lcdHTotal += (lcdHTotal << 1); } lcdHRetraceStart -=8; /* HBlank = HRetrace - 1: for */ lcdHRetraceEnd -=8; /* compatibility with vgaHW.c */ } else { /* use modeline values if bios values don't work */ lcdHTotal = mode->CrtcHTotal; lcdHRetraceStart = mode->CrtcHSyncStart; lcdHRetraceEnd = mode->CrtcHSyncEnd; } /* The chip takes the size of the visible display area from the * CRTC values. We use bios screensize for LCD in LCD/dual mode * wether or not we use modeline for LCD. This way we can specify * always specify a smaller than default display size on LCD * by writing it to the CRTC registers. */ lcdHDisplay = __svgalib_ctSize.HDisplay; if (modeinfo->bitsPerPixel == 16) { lcdHDisplay++; lcdHDisplay <<= 1; lcdHDisplay--; } else if (modeinfo->bitsPerPixel == 24) { lcdHDisplay++; lcdHDisplay += (lcdHDisplay << 1); lcdHDisplay--; } lcdHTotal = (lcdHTotal >> 3) - 5; lcdHDisplay = (lcdHDisplay >> 3) - 1; lcdHRetraceStart = (lcdHRetraceStart >> 3); lcdHRetraceEnd = (lcdHRetraceEnd >> 3); /* This ugly hack is needed because CR01 and XR1C share the 8th bit!*/ CrtcHDisplay = ((mode->CrtcHDisplay >> 3) - 1); if((lcdHDisplay & 0x100) != ( CrtcHDisplay & 0x100)){ printf("This display configuration might cause problems !\n"); lcdHDisplay = 255;} /* now init register values */ moderegs[XR17] = (((lcdHTotal) & 0x100) >> 8) | ((lcdHDisplay & 0x100) >> 7) | ((lcdHRetraceStart & 0x100) >> 6) | (((lcdHRetraceEnd) & 0x20) >> 2); moderegs[XR19] = lcdHRetraceStart & 0xFF; moderegs[XR1A] = lcdHRetraceEnd & 0x1F; moderegs[XR1B] = lcdHTotal & 0xFF; moderegs[XR1C] = lcdHDisplay & 0xFF; if (ctFlagsSet & ctFlags_UseModeline) { /* for ext. packed pixel mode on 64520/64530 */ /* no need to rescale: used only in 65530 */ moderegs[XR21] = lcdHRetraceStart & 0xFF; moderegs[XR22] = lcdHRetraceEnd & 0x1F; moderegs[XR23] = lcdHTotal & 0xFF; /* vertical timing registers */ lcdVTotal = mode->CrtcVTotal - 2; lcdVDisplay = __svgalib_ctSize.VDisplay - 1; lcdVRetraceStart = mode->CrtcVSyncStart; lcdVRetraceEnd = mode->CrtcVSyncEnd; moderegs[XR64] = lcdVTotal & 0xFF; moderegs[XR66] = lcdVRetraceStart & 0xFF; moderegs[XR67] = lcdVRetraceEnd & 0x0F; moderegs[XR68] = lcdVDisplay & 0xFF; moderegs[XR65] = ((lcdVTotal & 0x100) >> 8) | ((lcdVDisplay & 0x100) >> 7) | ((lcdVRetraceStart & 0x100) >> 6) | ((lcdVRetraceStart & 0x400) >> 7) | ((lcdVTotal & 0x400) >> 6) | ((lcdVTotal & 0x200) >> 4) | ((lcdVDisplay & 0x200) >> 3) | ((lcdVRetraceStart & 0x200) >> 2); /* * These are important: 0x2C specifies the numbers of lines * (hsync pulses) between vertical blank start and vertical * line total, 0x2D specifies the number of clock ticks? to * horiz. blank start ( caution ! 16bpp/24bpp modes: that's * why we need HSyncStart - can't use mode->CrtcHSyncStart) */ tmp = ((__svgalib_ctPanelType == DD) && !(moderegs[XR6F] & 0x02)) ? 1 : 0; /* double LP delay, FLM: 2 lines iff DD+no acc*/ /* Currently we support 2 FLM scemes: #1: FLM coincides with * VTotal ie. the delay is programmed to the difference bet- * ween lctVTotal and lcdVRetraceStart. #2: FLM coincides * lcdVRetraceStart - in this case FLM delay will be turned * off. To decide which sceme to use we compare the value of * XR2C set by the bios to the two scemes. The one that fits * better will be used. */ if (moderegs[XR2C] < abs((__svgalib_ctSize.VTotal - __svgalib_ctSize.VRetraceStart - tmp - 1) - moderegs[XR2C])) moderegs[XR2F] |= 0x80; /* turn FLM delay off */ moderegs[XR2C] = lcdVTotal - lcdVRetraceStart - tmp; /*moderegs[XR2D] = (HSyncStart >> (3 - tmp)) & 0xFF;*/ moderegs[XR2D] = (HDisplay >> (3 - tmp)) & 0xFF; moderegs[XR2F] = (moderegs[XR2F] & 0xDF) | (((HSyncStart >> (3 - tmp)) & 0x100) >> 3); } if ((ctFlagsSet & ctFlags_StretchEnable) || (ctFlagsSet & ctFlags_StretchDisable) || (ctFlagsSet & ctFlags_CenterEnable) || (ctFlagsSet & ctFlags_CenterDisable)) { moderegs[XR51] |= 0x40; /* enable FP compensation */ moderegs[XR55] |= 0x01; /* enable horiz compensation */ moderegs[XR57] |= 0x01; /* enable vert compensation */ moderegs[XR57] &= 0x7F; /* disable fast-centre */ moderegs[XR58] = 0; } /* Screen Centering */ moderegs[XR57]|=0x01; if (ctFlagsSet & ctFlags_CenterEnable) { moderegs[XR57] |= 0x02; /* enable v-centring */ if (mode->CrtcHDisplay < 1489) /* HWBug */ moderegs[XR55] |= 0x02; /* enable h-centring */ else if (modeinfo->bitsPerPixel == 24) { moderegs[XR55] &= ~0x02; moderegs[XR56] = (lcdHDisplay - CrtcHDisplay) >> 1; } } else if (ctFlagsSet & ctFlags_CenterDisable) { moderegs[XR55] &= 0xFD; /* disable h-centering */ moderegs[XR56] = 0; moderegs[XR57] &= 0xFD; /* disable v-centering */ } /* Screen Stretching */ if (ctFlagsSet & ctFlags_StretchEnable) { moderegs[XR55] |= 0x20; /* h-comp on, h-double off */ moderegs[XR57] |= 0x60; /* vertical stretching on */ printf("0x%X, 0x%X\n", mode->flags, DOUBLESCAN); printf("%d, %d\n", mode->CrtcVDisplay, __svgalib_ctSize.VDisplay); if (2*mode->CrtcVDisplay <= __svgalib_ctSize.VDisplay) { /* We assume that automatic double scanning occurs */ if (2 * mode->CrtcVDisplay == __svgalib_ctSize.VDisplay) temp = 0; else temp = (( 2 * mode->CrtcVDisplay) / (__svgalib_ctSize.VDisplay - (2 * mode->CrtcVDisplay))); } else { if (mode->CrtcVDisplay == __svgalib_ctSize.VDisplay) temp = 0; else temp = (mode->CrtcVDisplay / (__svgalib_ctSize.VDisplay - mode->CrtcVDisplay)); } moderegs[XR5A] = temp > 0x0F ? 0 : (unsigned char)temp; } else if (ctFlagsSet & ctFlags_StretchDisable) { moderegs[XR55] &= 0xDF; moderegs[XR57] &= 0x9F; } } moderegs[XR03] |= 0x02; /* 32 bit I/O enable etc. */ moderegs[XR07] = 0xF4; /* 32 bit I/O port selection */ moderegs[XR03] |= 0x08; /* High bandwidth on 65548 */ moderegs[XR40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp*/ moderegs[XR52] |= 0x01; /* Refresh count */ moderegs[XR0F] &= 0xEF; /* not Hi-/True-Colour */ moderegs[XR02] |= 0x01; /* 16bit CPU Memory Access */ moderegs[XR02] &= 0xE3; /* Attr. Cont. default access */ /* use ext. regs. for hor. in dual */ moderegs[XR06] &= 0xF3; /* bpp clear */ if (PCIcard) moderegs[XR03] |= 0x40; /* PCI Burst for 65548 */ /* sync. polarities */ if ((mode->flags & (PHSYNC | NHSYNC)) && (mode->flags & (PVSYNC | NVSYNC))) { if (mode->flags & (PHSYNC | NHSYNC)) { if (mode->flags & PHSYNC) { moderegs[XR55] &= 0xBF; /* CRT Hsync positive */ } else { moderegs[XR55] |= 0x40; /* CRT Hsync negative */ } } if (mode->flags & (PVSYNC | NVSYNC)) { if (mode->flags & PVSYNC) { moderegs[XR55] &= 0x7F; /* CRT Vsync positive */ } else { moderegs[XR55] |= 0x80; /* CRT Vsync negative */ } } } if (modeinfo->bitsPerPixel == 16) { moderegs[XR06] |= 0xC4; /*15 or 16 bpp colour */ moderegs[XR0F] |= 0x10; /*Hi-/True-Colour */ moderegs[XR40] = 0x02; /*BitBLT Draw Mode for 16 bpp */ if (modeinfo->greenWeight != 5) moderegs[XR06] |= 0x08; /*16bpp */ } else if (modeinfo->bitsPerPixel == 24) { moderegs[XR06] |= 0xC8; /*24 bpp colour */ moderegs[XR0F] |= 0x10; /*Hi-/True-Colour */ if (ctFlagsSet & ctFlags_Use18BitBus) { moderegs[XR50] &= 0x7F; /*18 bit TFT data width */ } else { moderegs[XR50] |= 0x80; /*24 bit TFT data width */ } } /* STN specific */ if (IS_STN(__svgalib_ctPanelType)) { moderegs[XR50] &= ~0x03; /* FRC clear */ moderegs[XR50] |= 0x01; /* 16 frame FRC */ moderegs[XR50] &= ~0x0C; /* Dither clear */ moderegs[XR50] |= 0x08; /* Dither all modes */ if (CHIPSchipset == CT_548) { moderegs[XR03] |= 0x20; /* CRT I/F priority */ moderegs[XR04] |= 0x10; /* RAS precharge 65548 */ } }}static void CHIPS_HiQV_initializemode(unsigned char *moderegs, ModeTiming * mode, ModeInfo * modeinfo){ int lcdHTotal, lcdHDisplay; int lcdVTotal, lcdVDisplay; int lcdHRetraceStart, lcdHRetraceEnd; int lcdVRetraceStart, lcdVRetraceEnd; int lcdHSyncStart; unsigned int temp;#ifdef DEBUG printf("CHIPS: CHIPS_HiQV_initializemode\n");#endif /* Get current values. Must be called before CalcClock */ CHIPS_saveregs(moderegs); /* Set up the standard VGA registers for a generic SVGA. */ __svgalib_setup_VGA_registers(moderegs, mode, modeinfo); /* init clock */#ifdef DEBUG printf("CHIPS: pixelclock used: %d\n",mode->pixelClock);#endif ctCalcClock(moderegs,mode->pixelClock); moderegs[VGA_AR10] = 0x01; /* mode */ moderegs[VGA_AR11] = 0x00; /* overscan (border) color */ moderegs[VGA_AR12] = 0x0F; /* enable all color planes */ moderegs[VGA_AR13] = 0x00; /* horiz pixel panning 0 */ moderegs[VGA_GR5] = 0x00; /* normal read/write mode */ temp = mode->CrtcHDisplay >> 3; /* bytes per scan line, 256 color mode */ if (modeinfo->bitsPerPixel == 24) { temp += temp << 1; /* -> x3 in 16M color mode */ } else if (modeinfo->bitsPerPixel == 16) { temp <<= 1; /* or x2 in 64K color mode */ } moderegs[VGA_CR13] = (temp) & 0xFF; /* bytes of fb memory per scan line */ moderegs[HiQVCR41] = (temp >> 8) & 0xF; /* upper 4 bits of it, as HiQVXR09[0] is set to 1 */ moderegs[HiQVXR0A] |= 0x1; /* Paging mode enabled, nolinear */ moderegs[HiQVXR09] |= 0x1; /* Enable extended CRT registers */ moderegs[HiQVXR0E] = 0; /* Single map */ moderegs[HiQVXR40] |= 0x3; /* High Resolution. XR40[1] reserved? */ moderegs[HiQVXR81] &= 0xF8; /* 256 Color Video */ moderegs[HiQVXR81] |= 0x2; moderegs[HiQVXR80] |= 0x10; /* Enable cursor output on P0 and P1 */ moderegs[HiQVXR20] = 0x0; /* BitBLT Draw mode for 8bpp */ /* panel timing */ /* By default don't set panel timings, but allow it as an option */ if (ctFlagsSet & ctFlags_UseModeline) { lcdHTotal = (mode->CrtcHTotal >> 3) - 5; lcdHDisplay = (__svgalib_ctSize.HDisplay >> 3) - 1; lcdHRetraceStart = (mode->CrtcHSyncStart >> 3); lcdHRetraceEnd = (mode->CrtcHSyncEnd >> 3); lcdHSyncStart = lcdHRetraceStart - 2; lcdVTotal = mode->CrtcVTotal - 2; lcdVDisplay = __svgalib_ctSize.VDisplay - 1; lcdVRetraceStart = mode->CrtcVSyncStart; lcdVRetraceEnd = mode->CrtcVSyncEnd;#ifdef MODELINE_DEBUG printf("lcdHTotal = %d, lcdHDisplay = %d, lcdHRetraceStart = %d\n", lcdHTotal,lcdHDisplay,lcdHRetraceStart); printf("lcdHRetraceEnd = %d, lcdHSyncStart = %d\n",lcdHRetraceEnd,lcdHSyncStart); printf("lcdVTotal = %d, lcdVDisplay = %d, lcdVretraceStart = %d\n", lcdVTotal,lcdVDisplay,lcdVRetraceStart); printf("before:\n"); printf("#20 = %02X, #21 = %02X, #22 = %02X, #23 = %02X, #24 = %02X, #25 = %02X\n", moderegs[HiQVFR20],moderegs[HiQVFR21],moderegs[HiQVFR22],moderegs[HiQVFR23], moderegs[HiQVFR24],moderegs[HiQVFR25]); printf("#26 = %02X, #27 = %02X\n", moderegs[HiQVFR26],moderegs[HiQVFR27]); printf("#30 = %02X, #31 = %02X, #32 = %02X, #33 = %02X, #34 = %02X, #35 = %02X\n", moderegs[HiQVFR30],moderegs[HiQVFR31],moderegs[HiQVFR32],moderegs[HiQVFR33], moderegs[HiQVFR34],moderegs[HiQVFR35]); printf("#36 = %02X, #37 = %02X\n", moderegs[HiQVFR36],moderegs[HiQVFR37]);#endif moderegs[HiQVFR20] = lcdHDisplay & 0xFF; moderegs[HiQVFR21] = lcdHRetraceStart & 0xFF; moderegs[HiQVFR25] = ((lcdHRetraceStart & 0xF00) >> 4) | ((lcdHDisplay & 0xF00) >> 8); moderegs[HiQVFR22] = lcdHRetraceEnd & 0x1F; moderegs[HiQVFR23] = lcdHTotal & 0xFF; moderegs[HiQVFR24] = (lcdHSyncStart >> 3) & 0xFF; moderegs[HiQVFR26] = (moderegs[HiQVFR26] & ~0x1F) | ((lcdHTotal & 0xF00) >> 8) | (((lcdHSyncStart >> 3) & 0x100) >> 4); moderegs[HiQVFR27] &= 0x7F; moderegs[HiQVFR30] = lcdVDisplay & 0xFF; moderegs[HiQVFR31] = lcdVRetraceStart & 0xFF; moderegs[HiQVFR35] = ((lcdVRetraceStart & 0xF00) >> 4) | ((lcdVDisplay & 0xF00) >> 8); moderegs[HiQVFR32] = lcdVRetraceEnd & 0x0F; moderegs[HiQVFR33] = lcdVTotal & 0xFF; moderegs[HiQVFR34] = (lcdVTotal - lcdVRetraceStart) & 0xFF; moderegs[HiQVFR36] = ((lcdVTotal & 0xF00) >> 8) | (((lcdVTotal - lcdVRetraceStart) & 0x700) >> 4); moderegs[HiQVFR37] |= 0x80;#ifdef MODELINE_DEBUG printf("after:\n"); printf("#20 = %02X, #21 = %02X, #22 = %02X, #23 = %02X, #24 = %02X, #25 = %02X\n", moderegs[HiQVFR20],moderegs[HiQVFR21],moderegs[HiQVFR22],moderegs[HiQVFR23], moderegs[HiQVFR24],moderegs[HiQVFR25]); printf("#26 = %02X, #27 = %02X\n", moderegs[HiQVFR26],moderegs[HiQVFR27]); printf("#30 = %02X, #31 = %02X, #32 = %02X, #33 = %02X, #34 = %02X, #35 = %02X\n", moderegs[HiQVFR30],moderegs[HiQVFR31],moderegs[HiQVFR32],moderegs[HiQVFR33], moderegs[HiQVFR34],moderegs[HiQVFR35]); printf("#36 = %02X, #37 = %02X\n", moderegs[HiQVFR36],moderegs[HiQVFR37]);#endif } /* Set up the extended CRT registers of the HiQV32 chips */ moderegs[HiQVCR30] = ((mode->CrtcVTotal - 2) & 0xF00) >> 8; moderegs[HiQVCR31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8; moderegs[HiQVCR32] = (mode->CrtcVSyncStart & 0xF00) >> 8; moderegs[HiQVCR33] = (mode->CrtcVSyncStart & 0xF00) >> 8; if (CHIPSchipset == CT_9000) { /* The 69000 has overflow bits for the horizontal values as well */ moderegs[HiQVCR38] = (((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8; moderegs[HiQVCR3C] = ((mode->CrtcHSyncEnd >> 3) & 0xC0); } /* Screen Centring */ if (ctFlagsSet & ctFlags_CenterEnable) { moderegs[HiQVFR40] |= 0x3; /* Enable Horizontal centering */ moderegs[HiQVFR48] |= 0x3; /* Enable Vertical centering */ } else if (ctFlagsSet & ctFlags_CenterDisable) { moderegs[HiQVFR40] &= 0xFD; /* Disable Horizontal centering */ moderegs[HiQVFR48] &= 0xFD; /* Disable Vertical centering */ } /* Screen Stretching */ if (ctFlagsSet & ctFlags_StretchEnable) { moderegs[HiQVFR40] |= 0x21; /* Enable Horizontal stretching */ moderegs[HiQVFR48] |= 0x05; /* Enable Vertical stretching */ } else if (ctFlagsSet & ctFlags_StretchDisable) { moderegs[HiQVFR40] &= 0xDF; /* Disable Horizontal stretching */ moderegs[HiQVFR48] &= 0xFB; /* Disable Vertical stretching */ } moderegs[HiQVXRE2] = ct_video_mode(modeinfo->bitsPerPixel, modeinfo->greenWeight,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -