nvidiacore.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 702 行 · 第 1/2 页

JAVA
702
字号
		int repaint1 = vgaIO.getCRT(NVCRTCX_REPAINT1);
		if (state.isHsync()) {
			repaint1 &= 0x7f;
		} else {
			repaint1 |= 0x80;
		}
		if (state.isVsync()) {
			repaint1 &= 0xbf;
		} else {
			repaint1 |= 0x40;
		}
		vgaIO.setCRT(NVCRTCX_REPAINT1, repaint1);
	}

	/**
	 * Gets the current DPMS state
	 * 
	 * @return
	 */
	private NVidiaDpmsState getDpms() {
		final boolean display = ((vgaIO.getSEQ(NVSEQX_CLKMODE) & 0x20) == 0);
		final int repaint1 = vgaIO.getCRT(NVCRTCX_REPAINT1);
		final boolean hsync = ((repaint1 & 0x80) == 0);
		final boolean vsync = ((repaint1 & 0x40) == 0);
		return new NVidiaDpmsState(display, hsync, vsync);
	}

	/**
	 * Start a DDC1 readout
	 */
	public void setupDDC1() {
		// Enable access to extended registers
		//vgaIO.unlock();
		vgaIO.setCRT(NVCRTCX_LOCK, 0x57);
	}

	/**
	 * Terminate a DDC1 readout
	 */
	public void closeDDC1() {
		// Disable access to extended registers
		//vgaIO.lock();
	}

	/**
	 * @see org.jnode.driver.video.ddc.DisplayDataChannelAPI#getDDC1Bit()
	 */
	public boolean getDDC1Bit() {
		/* wait for Vsync */
		while ((vgaIO.getSTAT() & 0x08) != 0) { /* wait */
		}
		while ((vgaIO.getSTAT() & 0x08) == 0) { /* wait */
		}

		/* Get the result */
		final int val = vgaIO.getCRT(DDCBase);
		//log.debug("getDDC1Bit: val=0x" + NumberUtils.hex(val, 2));
		return ((val & DDC_SDA_READ_MASK) != 0);
	}

	private void setPLL(DisplayMode mode) {
		final int[] best = calcVCLock(mode.getFreq());
		final int m = best[0];
		final int n = best[1];
		final int p = best[2];
		final int freq = best[3];
		log.info("Programming PLL to M" + NumberUtils.hex(m, 2) + " N" + NumberUtils.hex(n, 2) + " P" + NumberUtils.hex(p, 2) + " at " + freq + "KHz");

		// select pixelPLL registerset C
		vgaIO.setReg32(NVDAC_PLLSEL, 0x10000700);

		// program new frequency
		vgaIO.setReg32(NVDAC_PIXPLLC, ((p << 16) | (n << 8) | m));
	}

	/**
	 * Calculate the best VClock settings
	 * 
	 * @param clockIn
	 * @return The best values in the form of { M, N, P, clock }
	 */
	private int[] calcVCLock(int clockIn) {
		int DeltaOld = Integer.MAX_VALUE;
		final int VClk = clockIn;
		final int lowM;
		final int highM;
		final boolean isNV3 = (architecture < NV04A);
		if (CrystalFreqKHz == 14318) {
			lowM = 8;
			highM = 14 - (isNV3 ? 1 : 0);
		} else {
			lowM = 7;
			highM = 13 - (isNV3 ? 1 : 0);
		}
		final int highP = 4 - (isNV3 ? 1 : 0);
		final int best[] = new int[4];
		for (int P = 0; P <= highP; P++) {
			int Freq = VClk << P;
			if ((Freq >= 128000) && (Freq <= MaxVClockFreqKHz)) {
				for (int M = lowM; M <= highM; M++) {
					final int N = (VClk * M / CrystalFreqKHz) << P;
					final int DeltaNew;
					Freq = (CrystalFreqKHz * N / M) >> P;
					if (Freq > VClk) {
						DeltaNew = Freq - VClk;
					} else {
						DeltaNew = VClk - Freq;
					}
					if (DeltaNew < DeltaOld) {
						best[0] = M;
						best[1] = N;
						best[2] = P;
						best[3] = Freq;
						DeltaOld = DeltaNew;
					}
				}
			}
		}
		if (DeltaOld == Integer.MAX_VALUE) {
			throw new RuntimeException("Cannot find a suitable VClock");
		} else {
			return best;
		}
	}

	private void setTiming(DisplayMode mode) {
		log.info("Setting timing to " + mode);
		// Modify parameters as required by standard VGA
		final int htotal = ((mode.getHTotal() >> 3) - 5);
		final int hdisp_e = ((mode.getWidth() >> 3) - 1);
		final int hblnk_s = hdisp_e;
		final int hblnk_e = (htotal + 4); //0;
		final int hsync_s = (mode.getHsyncStart() >> 3);
		final int hsync_e = (mode.getHsyncEnd() >> 3);

		final int vtotal = mode.getVTotal() - 2;
		final int vdisp_e = mode.getHeight() - 1;
		final int vblnk_s = vdisp_e;
		final int vblnk_e = (vtotal + 1);
		final int vsync_s = mode.getVsyncStart(); //-1;
		final int vsync_e = mode.getVsyncEnd(); //-1;

		log.info("HOR:" + htotal + " " + hdisp_e + " " + hblnk_s + " " + hblnk_e + " " + hsync_s + " " + hsync_e);
		log.info("VER:" + vtotal + " " + vdisp_e + " " + vblnk_s + " " + vblnk_e + " " + vsync_s + " " + vsync_e);

		/*
		 * prevent memory adress counter from being reset (linecomp may not occur)
		 */
		final int linecomp = 0x3ff; // mode.getHeight();

		//	  fixme: flatpanel 'don't touch' update needed for 'Go' cards!?!
		if (true) {
			/* actually program the card! */
			/* unlock CRTC registers at index 0-7 */
			//vgaIO.setCRT(NVCRTCX_LOCK, 0x57);
			vgaIO.unlock();
			/* horizontal standard VGA regs */
			vgaIO.setCRT(NVCRTCX_HTOTAL, (htotal & 0xff));
			vgaIO.setCRT(NVCRTCX_HDISPE, (hdisp_e & 0xff));
			vgaIO.setCRT(NVCRTCX_HBLANKS, (hblnk_s & 0xff));
			/* also unlock vertical retrace registers in advance */
			vgaIO.setCRT(NVCRTCX_HBLANKE, ((hblnk_e & 0x1f) | 0x80));
			vgaIO.setCRT(NVCRTCX_HSYNCS, (hsync_s & 0xff));
			vgaIO.setCRT(NVCRTCX_HSYNCE, ((hsync_e & 0x1f) | ((hblnk_e & 0x20) << 2)));

			/* vertical standard VGA regs */
			vgaIO.setCRT(NVCRTCX_VTOTAL, (vtotal & 0xff));
			int overflow = 0;
			overflow |= ((vtotal & 0x100) >> (8 - 0)); // VDT_8
			overflow |= ((vdisp_e & 0x100) >> (8 - 1)); // VDE_8
			overflow |= ((vsync_s & 0x100) >> (8 - 2)); // VRS_8
			overflow |= ((vblnk_s & 0x100) >> (8 - 3)); // VBS_8
			overflow |= ((vtotal & 0x200) >> (9 - 5)); // VDT_9
			overflow |= ((vdisp_e & 0x200) >> (9 - 6)); // VDE_9
			overflow |= ((vsync_s & 0x200) >> (9 - 7)); // VRS_9
			vgaIO.setCRT(NVCRTCX_OVERFLOW, overflow);
			vgaIO.setCRT(NVCRTCX_PRROWSCN, 0x00); /* not used */

			int maxsclin = 0;
			maxsclin |= ((vblnk_s & 0x200) >> (9 - 5)); // VBS_9
			maxsclin |= ((linecomp & 0x200) >> (9 - 6)); // LC_9
			vgaIO.setCRT(NVCRTCX_MAXSCLIN, maxsclin);
			vgaIO.setCRT(NVCRTCX_VSYNCS, (vsync_s & 0xff));
			vgaIO.setCRT(NVCRTCX_VSYNCE, ((vgaIO.getCRT(NVCRTCX_VSYNCE) & 0x70) | (vsync_e & 0x0f)));
			vgaIO.setCRT(NVCRTCX_VDISPE, (vdisp_e & 0xff));
			vgaIO.setCRT(NVCRTCX_VBLANKS, (vblnk_s & 0xff));
			vgaIO.setCRT(NVCRTCX_VBLANKE, (vblnk_e & 0xff));
			vgaIO.setCRT(NVCRTCX_LINECOMP, (linecomp & 0xff));

			/* horizontal extended regs */
			int heb = vgaIO.getCRT(NVCRTCX_HEB) & 0xe0;
			heb |= ((htotal & 0x100) >> (8 - 0)); // HDT_8
			heb |= ((hdisp_e & 0x100) >> (8 - 1)); // HDE_8
			heb |= ((hblnk_s & 0x100) >> (8 - 2)); // HBS_8
			heb |= ((hsync_s & 0x100) >> (8 - 3)); // HRS_8
			heb |= ((linecomp & 0x100) >> (8 - 4)); // ILC_8
			vgaIO.setCRT(NVCRTCX_HEB, heb);

			/* (mostly) vertical extended regs */
			int lsr = vgaIO.getCRT(NVCRTCX_LSR) & 0xc0;
			lsr |= ((vtotal & 0x400) >> (10 - 0)); // VDT_10
			lsr |= ((vdisp_e & 0x400) >> (10 - 1)); // VDE_10
			lsr |= ((vsync_s & 0x400) >> (10 - 2)); // VRS_10
			lsr |= ((vblnk_s & 0x400) >> (10 - 3)); // VRBS_10
			lsr |= ((hblnk_e & 0x040) >> (6 - 4)); // HBE_6
			vgaIO.setCRT(NVCRTCX_LSR, lsr);

			// extra
			int ebr = 0;
			ebr |= ((vtotal & 0x800) >> (11 - 0)); // VDT_11
			ebr |= ((vdisp_e & 0x800) >> (11 - 2)); // VDE_11
			ebr |= ((vsync_s & 0x800) >> (11 - 4)); // VRS_11
			ebr |= ((vblnk_s & 0x800) >> (11 - 8)); // VBS_11
			vgaIO.setCRT(NVCRTCX_EBR, ebr);

			/* setup 'large screen' mode */
			final int repaint1 = vgaIO.getCRT(NVCRTCX_REPAINT1);
			if (mode.getWidth() >= 1280) {
				vgaIO.setCRT(NVCRTCX_REPAINT1, (repaint1 & 0xfb));
			} else {
				vgaIO.setCRT(NVCRTCX_REPAINT1, (repaint1 | 0x04));
			}

			/* setup HSYNC & VSYNC polarity */
			/*
			 * LOG(2, ("CRTC: sync polarity: ")); int temp = vgaIO.getReg8(NV8_MISCR); if (target.timing.flags & B_POSITIVE_HSYNC) { LOG(2, ("H:pos ")); temp &= ~0x40; } else { LOG(2, ("H:neg "));
			 * temp |= 0x40; } if (target.timing.flags & B_POSITIVE_VSYNC) { LOG(2, ("V:pos ")); temp &= ~0x80; } else { LOG(2, ("V:neg ")); temp |= 0x80; }
			 */
		}
	}

	private final void setPalette(float brightness) {
		vgaIO.setReg8(NV8_PALMASK, 0xff);
		for (int i = 0; i < 256; i++) {
			int v = (int) (i * brightness);
			if (v > 255) {
				v = 255;
			}
			vgaIO.setDACWriteIndex(i);
			vgaIO.setDACData(v); // r
			vgaIO.setDACData(v); // g
			vgaIO.setDACData(v); // b
		}
	}

	/**
	 * Gets the hardware cursor implementation
	 */
	public NVidiaHardwareCursor getHardwareCursor() {
		return hwCursor;
	}
	/**
	 * @see org.jnode.driver.video.util.AbstractSurface#fillRect(int, int, int, int, int, int)
	 */
	protected void fillRect(int x, int y, int w, int h, int color, int mode) {
		final int screenWidth = config.getScreenWidth();
		if (x + w >= screenWidth) {
			w = screenWidth - x;				
		}
		if (useAcc && (mode == PAINT_MODE)) {
			acc.setupRectangle(color);
			acc.fillRectangle(x, y, w, h);
		} else {
			if ((x == 0) && (w == screenWidth)) {
				bitmapGraphics.drawPixels(0, y, screenWidth * height, color, mode);
			} else {
				super.fillRect(x, y, w, h, color, mode);
			}
		}
	}

	/**
	 * Detect the size of installed memory.
	 * 
	 * @return Size in MB.
	 */
	private final int getMemorySize() {
		final int size;
		if (architecture == NV04A) {
			final int strapinfo = vgaIO.getReg32(NV32_NV4STRAPINFO);

			if ((strapinfo & 0x00000100) != 0) {
				/* Unified memory architecture used */
				log.info("INFO: NV4 architecture chip with UMA detected");
				size = ((((strapinfo & 0x0000f000) >> 12) * 2) + 2);

			} else {
				/* private memory architecture used */
				switch (strapinfo & 0x00000003) {
					case 0 :
						size = 32;
						break;
					case 1 :
						size = 4;
						break;
					case 2 :
						size = 8;
						break;
					case 3 :
						size = 16;
						break;
					default :
						// Cannot get here, but just to keep the compiler silent.
						size = 8;
				}
			}
		} else {
			// NV10, NV20
			//final int dev_manID = CFGR(DEVID);
			final int strapinfo = vgaIO.getReg32(NV32_NV10STRAPINFO);

			//case 0x01a010de: /* Nvidia GeForce2 Integrated GPU */
			//	size = (((CFGR(GF2IGPU) & 0x000007c0) >> 6) + 1);
			//	break;
			//case 0x01f010de: /* Nvidia GeForce4 MX Integrated GPU */
			//	size = (((CFGR(GF4MXIGPU) & 0x000007f0) >> 4) + 1);
			//remove this line if det. is OK: int amt = pciReadLong(pciTag(0, 0, 1), 0x84);
			//	break;
			switch ((strapinfo & 0x0ff00000) >> 20) {
				case 2 :
					size = 2;
					break;
				case 4 :
					size = 4;
					break;
				case 8 :
					size = 8;
					break;
				case 16 :
					size = 16;
					break;
				case 32 :
					size = 32;
					break;
				case 64 :
					size = 64;
					break;
				case 128 :
					size = 128;
					break;
				default :
					size = 16;
					log.info("NV10/20 architecture chip with unknown RAM amount detected, setting 16Mb");
					break;
			}
		}
		return size;
	}

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?