📄 atimode.c
字号:
{ /* Save VGA data */ ATIVGASave(pATI, pATIHW); /* Save VGA Wonder data */ if (pATI->CPIO_VGAWonder) ATIVGAWonderSave(pATI, pATIHW); } if (pATI->Chip >= ATI_CHIP_88800GXC)#endif /* AVOID_CPIO */ { /* Save Mach64 data */ ATIMach64Save(pATI, pATIHW); if (pATI->Chip >= ATI_CHIP_264VTB) { /* Save DSP data */ ATIDSPSave(pATI, pATIHW); if (pATI->LCDPanelID >= 0) { /* Switch to shadow registers */ if (pATI->Chip == ATI_CHIP_264LT) outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN); else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ ATIMach64PutLCDReg(LCD_GEN_CNTL, (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);#ifndef AVOID_CPIO /* Save shadow VGA CRTC registers */ for (Index = 0; Index < NumberOf(pATIHW->shadow_vga); Index++) pATIHW->shadow_vga[Index] = GetReg(CRTX(pATI->CPIO_VGABase), Index);#endif /* AVOID_CPIO */ /* Save shadow Mach64 CRTC registers */ pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP); pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID); pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP); pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID); /* Restore CRTC selection and shadow state */ if (pATI->Chip == ATI_CHIP_264LT) { outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl); } else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ { ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl); outr(LCD_INDEX, pATIHW->lcd_index); } } } else if (pATI->DAC == ATI_DAC_IBMRGB514) ATIRGB514Save(pATI, pATIHW); }#ifndef AVOID_CPIO /* * For some unknown reason, CLKDIV2 needs to be turned off to save the * DAC's LUT reliably on VGA Wonder VLB adapters. */ if ((pATI->Adapter == ATI_ADAPTER_NONISA) && (pATIHW->seq[1] & 0x08U)) PutReg(SEQX, 0x01U, pATIHW->seq[1] & ~0x08U);#endif /* AVOID_CPIO */ /* Save RAMDAC state */ ATIDACSave(pATI, pATIHW);#ifndef AVOID_CPIO if ((pATI->Adapter == ATI_ADAPTER_NONISA) && (pATIHW->seq[1] & 0x08U)) PutReg(SEQX, 0x01U, pATIHW->seq[1]);#endif /* AVOID_CPIO */ /* * The server has already saved video memory contents when switching out of * its virtual console, so don't do it again. */ if (pATIHW != &pATI->NewHW) { pATIHW->FeedbackDivider = 0; /* Don't programme clock */#ifndef AVOID_CPIO /* Save video memory */ ATISwap(pScreenInfo->scrnIndex, pATI, pATIHW, FALSE);#endif /* AVOID_CPIO */ }#ifndef AVOID_CPIO if (pATI->VGAAdapter != ATI_ADAPTER_NONE) ATIVGASaveScreen(pATI, SCREEN_SAVER_OFF); /* Turn on screen */#endif /* AVOID_CPIO */}/* * ATIModeCalculate -- * * This function fills in an ATIHWRec with all register values needed to enable * a video state. It's important that this be done without modifying the * current video state. */BoolATIModeCalculate( int iScreen, ATIPtr pATI, ATIHWPtr pATIHW, DisplayModePtr pMode){ CARD32 lcd_index; int Index, ECPClock, MaxScalerClock; /* Clobber mode timings */ if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0) && !pMode->CrtcHAdjusted && !pMode->CrtcVAdjusted && (!pATI->OptionLCDSync || (pMode->type & M_T_BUILTIN))) { int VScan; pMode->Clock = pATI->LCDClock; pMode->Flags &= ~(V_DBLSCAN | V_INTERLACE | V_CLKDIV2); /* * Use doublescanning or multiscanning to get around vertical blending * limitations. */ VScan = pATI->LCDVertical / pMode->VDisplay; switch (pATIHW->crtc) {#ifndef AVOID_CPIO case ATI_CRTC_VGA: if (VScan > 64) VScan = 64; pMode->VScan = VScan; break;#endif /* AVOID_CPIO */ case ATI_CRTC_MACH64: pMode->VScan = 0; if (VScan <= 1) break; VScan = 2; pMode->Flags |= V_DBLSCAN; break; default: break; } pMode->HSyncStart = pMode->HDisplay + pATI->LCDHSyncStart; pMode->HSyncEnd = pMode->HSyncStart + pATI->LCDHSyncWidth; pMode->HTotal = pMode->HDisplay + pATI->LCDHBlankWidth; pMode->VSyncStart = pMode->VDisplay + ATIDivide(pATI->LCDVSyncStart, VScan, 0, 0); pMode->VSyncEnd = pMode->VSyncStart + ATIDivide(pATI->LCDVSyncWidth, VScan, 0, 1); pMode->VTotal = pMode->VDisplay + ATIDivide(pATI->LCDVBlankWidth, VScan, 0, 0); } switch (pATIHW->crtc) {#ifndef AVOID_CPIO case ATI_CRTC_VGA: /* Fill in VGA data */ ATIVGACalculate(pATI, pATIHW, pMode); /* Fill in VGA Wonder data */ if (pATI->CPIO_VGAWonder) ATIVGAWonderCalculate(pATI, pATIHW, pMode); if (pATI->Chip >= ATI_CHIP_88800GXC) { if (pATI->Chip >= ATI_CHIP_264CT) { /* * Selected bits of accelerator & VGA CRTC registers are * actually copies of each other. */ pATIHW->crtc_h_total_disp = SetBits(pMode->CrtcHTotal, CRTC_H_TOTAL) | SetBits(pMode->CrtcHDisplay, CRTC_H_DISP); pATIHW->crtc_h_sync_strt_wid = SetBits(pMode->CrtcHSyncStart, CRTC_H_SYNC_STRT) | SetBits(pMode->CrtcHSkew, CRTC_H_SYNC_DLY) | /* ? */ SetBits(GetBits(pMode->CrtcHSyncStart, 0x0100U), CRTC_H_SYNC_STRT_HI) | SetBits(pMode->CrtcHSyncEnd, CRTC_H_SYNC_WID); if (pMode->Flags & V_NHSYNC) pATIHW->crtc_h_sync_strt_wid |= CRTC_H_SYNC_POL; pATIHW->crtc_v_total_disp = SetBits(pMode->CrtcVTotal, CRTC_V_TOTAL) | SetBits(pMode->CrtcVDisplay, CRTC_V_DISP); pATIHW->crtc_v_sync_strt_wid = SetBits(pMode->CrtcVSyncStart, CRTC_V_SYNC_STRT) | SetBits(pMode->CrtcVSyncEnd, CRTC_V_SYNC_END_VGA); if (pMode->Flags & V_NVSYNC) pATIHW->crtc_v_sync_strt_wid |= CRTC_V_SYNC_POL; } pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL) & ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN | CRTC_PIX_BY_2_EN | CRTC_DISPLAY_DIS | CRTC_VGA_XOVERSCAN | CRTC_PIX_WIDTH | CRTC_BYTE_PIX_ORDER | CRTC_VGA_128KAP_PAGING | CRTC_VFC_SYNC_TRISTATE | CRTC_LOCK_REGS | /* Already off, but ... */ CRTC_SYNC_TRISTATE | CRTC_EXT_DISP_EN | CRTC_DISP_REQ_EN | CRTC_VGA_LINEAR | CRTC_VGA_TEXT_132 | CRTC_CUR_B_TEST); /* Some of these are not relevent, but that doesn't matter */ switch (pATI->depth) { case 1: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_1BPP, CRTC_PIX_WIDTH); break; case 4: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_4BPP, CRTC_PIX_WIDTH); break; case 8: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_8BPP, CRTC_PIX_WIDTH); break; case 15: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_15BPP, CRTC_PIX_WIDTH); break; case 16: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_16BPP, CRTC_PIX_WIDTH); break; case 24: if (pATI->bitsPerPixel == 24) { pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_24BPP, CRTC_PIX_WIDTH); break; } if (pATI->bitsPerPixel != 32) break; /* Fall through */ case 32: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_32BPP, CRTC_PIX_WIDTH); break; default: break; }#if 0 /* This isn't needed, but is kept for reference */ if (pMode->Flags & V_DBLSCAN) pATIHW->crtc_gen_cntl |= CRTC_DBL_SCAN_EN;#endif if (pMode->Flags & V_INTERLACE) pATIHW->crtc_gen_cntl |= CRTC_INTERLACE_EN; if ((pMode->Flags & (V_CSYNC | V_PCSYNC)) || pATI->OptionCSync) pATIHW->crtc_gen_cntl |= CRTC_CSYNC_EN; if (pATI->depth <= 4) pATIHW->crtc_gen_cntl |= CRTC_EN | CRTC_CNT_EN; else pATIHW->crtc_gen_cntl |= CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN; } break;#endif /* AVOID_CPIO */ case ATI_CRTC_MACH64: /* Fill in Mach64 data */ ATIMach64Calculate(pATI, pATIHW, pMode); break; default: break; } /* Set up LCD register values */ if (pATI->LCDPanelID >= 0) { int VDisplay = pMode->VDisplay; if (pMode->Flags & V_DBLSCAN) VDisplay <<= 1; if (pMode->VScan > 1) VDisplay *= pMode->VScan; if (pMode->Flags & V_INTERLACE) VDisplay >>= 1; /* Ensure secondary CRTC is completely disabled */ pATIHW->crtc_gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); if (pATI->Chip == ATI_CHIP_264LT) { pATIHW->horz_stretching = inr(HORZ_STRETCHING); } else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ { lcd_index = inr(LCD_INDEX); pATIHW->horz_stretching = ATIMach64GetLCDReg(LCD_HORZ_STRETCHING); pATIHW->ext_vert_stretch = ATIMach64GetLCDReg(LCD_EXT_VERT_STRETCH) & ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3); /* * Don't use vertical blending if the mode is too wide or not * vertically stretched. */ if (pATI->OptionPanelDisplay && (pMode->HDisplay <= pATI->LCDVBlendFIFOSize) && (VDisplay < pATI->LCDVertical)) pATIHW->ext_vert_stretch |= VERT_STRETCH_MODE; outr(LCD_INDEX, lcd_index); } pATIHW->horz_stretching &= ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | HORZ_STRETCH_MODE | HORZ_STRETCH_EN); if (pATI->OptionPanelDisplay && (pMode->HDisplay < pATI->LCDHorizontal)) do { /* * The horizontal blender misbehaves when HDisplay is less than a * a certain threshold (440 for a 1024-wide panel). It doesn't * stretch such modes enough. Use pixel replication instead of * blending to stretch modes that can be made to exactly fit the * panel width. The undocumented "NoLCDBlend" option allows the * pixel-replicated mode to be slightly wider or narrower than the * panel width. It also causes a mode that is exactly half as wide * as the panel to be pixel-replicated, rather than blended. */ int HDisplay = pMode->HDisplay & ~7; int nStretch = pATI->LCDHorizontal / HDisplay; int Remainder = pATI->LCDHorizontal % HDisplay; if ((!Remainder && ((nStretch > 2) || !pATI->OptionBlend)) || (((HDisplay * 16) / pATI->LCDHorizontal) < 7)) { static const char StretchLoops[] = {10, 12, 13, 15, 16}; int horz_stretch_loop = -1, BestRemainder; int Numerator = HDisplay, Denominator = pATI->LCDHorizontal; ATIReduceRatio(&Numerator, &Denominator); BestRemainder = (Numerator * 16) / Denominator; Index = NumberOf(StretchLoops); while (--Index >= 0) { Remainder = ((Denominator - Numerator) * StretchLoops[Index]) % Denominator; if (Remainder < BestRemainder) { horz_stretch_loop = Index; if (!(BestRemainder = Remainder)) break; }#if 0 /* * Enabling this code allows the pixel-replicated mode to * be slightly wider than the panel width. */ Remainder = Denominator - Remainder; if (Remainder < BestRemainder) { horz_stretch_loop = Index; BestRemainder = Remainder; }#endif } if ((horz_stretch_loop >= 0) && (!BestRemainder || !pATI->OptionBlend)) { int horz_stretch_ratio = 0, Accumulator = 0; int reuse_previous = 1; Index = StretchLoops[horz_stretch_loop]; while (--Index >= 0) { if (Accumulator > 0) horz_stretch_ratio |= reuse_previous; else Accumulator += Denominator; Accumulator -= Numerator; reuse_previous <<= 1; } pATIHW->horz_stretching |= HORZ_STRETCH_EN | SetBits(horz_stretch_loop, HORZ_STRETCH_LOOP) | SetBits(horz_stretch_ratio, HORZ_STRETCH_RATIO); break; /* Out of the do { ... } while (0) */ } } pATIHW->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN) | SetBits((HDisplay * (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -