/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.driver.video.nvidia; import java.awt.Color; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.image.ColorModel; import java.awt.image.Raster; import javax.naming.NameNotFoundException; import org.apache.log4j.Logger; import org.jnode.awt.util.BitmapGraphics; import org.jnode.driver.DriverException; import org.jnode.driver.bus.pci.PCIBaseAddress; import org.jnode.driver.bus.pci.PCIDevice; import org.jnode.driver.bus.pci.PCIHeaderType0; import org.jnode.driver.video.FrameBufferConfiguration; import org.jnode.driver.video.ddc.DisplayDataChannelAPI; import org.jnode.driver.video.spi.DpmsState; import org.jnode.driver.video.util.AbstractSurface; import org.jnode.driver.video.vgahw.DisplayMode; import org.jnode.naming.InitialNaming; import org.jnode.system.resource.MemoryResource; import org.jnode.system.resource.ResourceManager; import org.jnode.system.resource.ResourceNotFreeException; import org.jnode.util.NumberUtils; import org.vmmagic.unboxed.Address; /** * @author Ewout Prangsma (epr@users.sourceforge.net) */ public class NVidiaCore extends AbstractSurface implements NVidiaConstants, DisplayDataChannelAPI { /** Acceleration functions */ private final NVidiaAcceleration acc; private final int architecture; private BitmapGraphics bitmapGraphics; private int bitsPerPixel = 32; private int bytesPerLine; private FrameBufferConfiguration config; private final int CrystalFreqKHz; private final int DDCBase = 0x3e; private final NVidiaDriver driver; /** Hardware cursor implementation */ private final NVidiaHardwareCursor hwCursor; /** My logger */ private static final Logger log = Logger.getLogger(NVidiaCore.class); private final int MaxVClockFreqKHz; /** Size of card memory in MB */ private final int memSize; private final MemoryResource mmio; private final NVidiaVgaState oldVgaState = new NVidiaVgaState(); /** Should acceleration be used */ private final boolean useAcc = true; private final NVidiaVgaIO vgaIO; private final MemoryResource videoRam; /** * @param driver * @param architecture * @param model * @param device */ public NVidiaCore(NVidiaDriver driver, int architecture, String model, PCIDevice device) throws ResourceNotFreeException, DriverException { super(640, 480); this.driver = driver; this.architecture = architecture; final PCIHeaderType0 pciCfg = device.getConfig().asHeaderType0(); final PCIBaseAddress ioAddr = pciCfg.getBaseAddresses()[0]; final PCIBaseAddress fbAddr = pciCfg.getBaseAddresses()[1]; log.info("Found NVidia " + model + ", chipset 0x" + NumberUtils.hex(pciCfg.getRevision())); try { final ResourceManager rm = InitialNaming.lookup(ResourceManager.NAME); final int ioBase = (int) ioAddr.getMemoryBase() & 0xFF800000; final int ioSize = ioAddr.getSize(); final int fbBase = (int) fbAddr.getMemoryBase() & 0xFF800000; final int fbSize = fbAddr.getSize(); log.debug("Found NVidia, FB at 0x" + NumberUtils.hex(fbBase) + "s0x" + NumberUtils.hex(fbSize) + ", MMIO at 0x" + NumberUtils.hex(ioBase)); this.mmio = rm.claimMemoryResource(device, Address.fromIntZeroExtend(ioBase), ioSize, ResourceManager.MEMMODE_NORMAL); this.videoRam = rm.claimMemoryResource(device, Address.fromIntZeroExtend(fbBase), fbSize, ResourceManager.MEMMODE_NORMAL); this.vgaIO = new NVidiaVgaIO(mmio, videoRam); } catch (NameNotFoundException ex) { throw new ResourceNotFreeException(ex); } this.hwCursor = new NVidiaHardwareCursor(vgaIO, architecture); this.acc = new NVidiaAcceleration(vgaIO, architecture); this.memSize = getMemorySize(); int bootInfo; switch (architecture) { case NV04A: bootInfo = vgaIO.getReg32(NV32_NVSTRAPINFO2); CrystalFreqKHz = ((bootInfo & 0x00000040) != 0) ? 14318 : 13500; MaxVClockFreqKHz = 250000; break; case NV10A: bootInfo = vgaIO.getReg32(NV32_NVSTRAPINFO2); CrystalFreqKHz = ((bootInfo & 0x00000040) != 0) ? 14318 : 13500; MaxVClockFreqKHz = 350000; break; case NV28M: bootInfo = vgaIO.getReg32(NV32_NVSTRAPINFO2); CrystalFreqKHz = ((bootInfo & 0x00000040) != 0) ? 14318 : 13500; MaxVClockFreqKHz = 200000; break; default: throw new DriverException("Unknown architecture " + architecture); } log.debug("Memory size =" + memSize + "MB"); log.debug("CrystalFreqKHz =" + CrystalFreqKHz); log.debug("MaxVClockFreqKHz=" + MaxVClockFreqKHz); } /** * 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; } } /** * Close the SVGA screen * * @see org.jnode.driver.video.Surface#close() */ public synchronized void close() { log.debug("close"); hwCursor.closeCursor(); final DpmsState dpmsState = getDpms(); log.debug("Old DPMS state: " + dpmsState); setDpms(DpmsState.OFF); vgaIO.unlock(); log.debug("restore old VGA state"); oldVgaState.restoreToVGA(vgaIO); log.debug("restore DPMS state"); setDpms(dpmsState); // For debugging purposes // final NVidiaVgaState debugState = new NVidiaVgaState(); // debugState.saveFromVGA(vgaIO); // log.debug("Restored state: " + debugState); // End of debugging purposes driver.close(this); super.close(); log.debug("End of close"); } /** * Terminate a DDC1 readout */ public void closeDDC1() { // Disable access to extended registers // vgaIO.lock(); } /** * @see org.jnode.driver.video.util.AbstractSurface#convertColor(java.awt.Color) */ protected int convertColor(Color color) { return color.getRGB(); } /** * @see org.jnode.driver.video.Surface#copyArea(int, int, int, int, int, * int) */ public void copyArea(int x, int y, int width, int height, int dx, int dy) { bitmapGraphics.copyArea(x, y, width, height, dx, dy); } /** * @see org.jnode.driver.video.Surface#drawCompatibleRaster(java.awt.image.Raster, * int, int, int, int, int, int, java.awt.Color) */ public final void drawCompatibleRaster(Raster raster, int srcX, int srcY, int dstX, int dstY, int width, int height, Color bgColor) { if (bgColor == null) { bitmapGraphics.drawImage(raster, srcX, srcY, dstX, dstY, width, height); } else { bitmapGraphics.drawImage(raster, srcX, srcY, dstX, dstY, width, height, convertColor(bgColor)); } } /** * @see org.jnode.driver.video.util.AbstractSurface#drawPixel(int, int, int, * int) */ public final void drawPixel(int x, int y, int color, int mode) { bitmapGraphics.drawPixels(x, y, 1, color, mode); } /** * @see org.jnode.driver.video.util.AbstractSurface#fillRect(int, int, int, * int, int, int) */ public 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); } } } /** * @see org.jnode.driver.video.Surface#getColorModel() */ public ColorModel getColorModel() { return config.getColorModel(); } /** * @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); } /** * Gets the current DPMS state * * @return */ private DpmsState 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 DpmsState(display, hsync, vsync); } /** * Gets the hardware cursor implementation */ public NVidiaHardwareCursor getHardwareCursor() { return hwCursor; } /** * 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.debug("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; log.info("strapinfo " + strapinfo); 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; } /** * Gets the start address of the video memory */ final int getVideoStartAddress() { int startadd = 0; if (architecture < NV10A) { /* upto 32Mb RAM adressing: must be used this way on pre-NV10! */ /* set standard registers */ /* (NVidia: startadress in 32bit words (b2 - b17) */ startadd |= ((vgaIO.getCRT(NVCRTCX_FBSTADDL) & 0xFF) << 2); startadd |= ((vgaIO.getCRT(NVCRTCX_FBSTADDH) & 0xFF) << 10); /* set extended registers */ /* NV4 extended bits: (b18-22) */ int temp = vgaIO.getCRT(NVCRTCX_REPAINT0) & 0x1f; startadd |= (temp << 18); /* NV4 extended bits: (b23-24) */ temp = vgaIO.getCRT(NVCRTCX_HEB) & 0x60; startadd |= (temp << 18); } else { /* upto 4Gb RAM adressing: must be used on NV10 and later! */ /* * NOTE: While this register also exists on pre-NV10 cards, it will * wrap-around at 16Mb boundaries!! */ /* 30bit adress in 32bit words */ startadd = vgaIO.getReg32(NV32_NV10FBSTADD32) & 0xfffffffc; } return startadd; } /** * Open the given configuration * * @param config */ final void open(NVidiaConfiguration config) { this.config = config; // Save the current state oldVgaState.saveFromVGA(vgaIO); // log.debug("Old VGA State: " + oldVgaState); // log.debug("Old start address:0x" + // NumberUtils.hex(getVideoStartAddress())); // Enabled access to extended registers vgaIO.unlock(); // Turn off the screen final DpmsState dpmsState = getDpms(); // log.debug("Old DPMS state: " + dpmsState); setDpms(DpmsState.OFF); /* power-up all nvidia hardware function blocks */ /* * bit 28: OVERLAY ENGINE (BES), bit 25: CRTC2, (> NV04A) bit 24: CRTC1, * bit 20: framebuffer, bit 16: PPMI, bit 12: PGRAPH, bit 8: PFIFO, bit * 4: PMEDIA, bit 0: TVOUT. (> NV04A) */ // log.debug("PWRUPCTRL=0x" + // NumberUtils.hex(mmio.getInt(NV32_PWRUPCTRL))); mmio.setInt(NV32_PWRUPCTRL, 0x13111111); // Set the new configuration this.bitsPerPixel = config.getBitsPerPixel(); this.width = config.getScreenWidth(); this.height = config.getScreenHeight(); final int pixelDepth = (this.bitsPerPixel + 1) / 8; this.bytesPerLine = width * pixelDepth; final int startAddress = 2048; try { final NVidiaVgaState newState = config.getVgaState(); newState.calcForConfiguration(config, architecture, vgaIO); newState.restoreToVGA(vgaIO); setPLL(config.getMode()); // setColourDepth setPalette(1.0f); // setDacMode setPitch(bytesPerLine); setVideoStartAddress(startAddress); setTiming(config.getMode()); hwCursor.initCursor(); // Setup accelration acc.accInit(startAddress, bytesPerLine, memSize, bitsPerPixel); } catch (Exception ex) { ex.printStackTrace(); } // Create the graphics helper & clear the screen final int pixels = width * height; switch (bitsPerPixel) { case 8: bitmapGraphics = BitmapGraphics.create8bppInstance(videoRam, width, height, bytesPerLine, startAddress); videoRam.setByte(startAddress, (byte) 0, pixels); break; case 16: bitmapGraphics = BitmapGraphics.create16bppInstance(videoRam, width, height, bytesPerLine, startAddress); videoRam.setShort(startAddress, (byte) 0, pixels); break; case 24: bitmapGraphics = BitmapGraphics.create24bppInstance(videoRam, width, height, bytesPerLine, startAddress); videoRam.setInt24(startAddress, 0, pixels); break; case 32: bitmapGraphics = BitmapGraphics.create32bppInstance(videoRam, width, height, bytesPerLine, startAddress); videoRam.setInt(startAddress, 0, pixels); break; } // Turn the screen back on setDpms(dpmsState); } /** * Release all resources */ final void release() { mmio.release(); videoRam.release(); } private void setDpms(DpmsState state) { // log.debug("Setting DPMS to " + state); /* start synchronous reset: required before turning screen off! */ vgaIO.setSEQ(NVSEQX_RESET, 0x01); /* turn screen off */ int clkmode = vgaIO.getSEQ(NVSEQX_CLKMODE); if (state.isDisplay()) { vgaIO.setSEQ(NVSEQX_CLKMODE, clkmode & ~0x20); /* end synchronous reset if display should be enabled */ vgaIO.setSEQ(NVSEQX_RESET, 0x03); } else { vgaIO.setSEQ(NVSEQX_CLKMODE, clkmode | 0x20); } 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); } 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 } } private void setPitch(int bytesPerLine) { final int offset = bytesPerLine / 8; // log.info("setPitch: offset 0x" + NumberUtils.hex(offset) + " // bytesPerLine 0x" + NumberUtils.hex(bytesPerLine)); // program the card! vgaIO.setCRT(NVCRTCX_PITCHL, offset & 0x00ff); final int temp = vgaIO.getCRT(NVCRTCX_REPAINT0); vgaIO.setCRT(NVCRTCX_REPAINT0, (temp & 0x1f) | ((offset & 0x0700) >> 3)); } 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.debug("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)); } private void setTiming(DisplayMode mode) { log.debug("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.debug("HOR:" + htotal + " " + hdisp_e + " " + hblnk_s + " " + hblnk_e + " " + hsync_s + " " + hsync_e); log.debug("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; } */ } } /** * Start a DDC1 readout */ public void setupDDC1() { // Enable access to extended registers // vgaIO.unlock(); vgaIO.setCRT(NVCRTCX_LOCK, 0x57); } /** * Sets the start address of the video memory * * @param startadd */ private void setVideoStartAddress(int startadd) { if (architecture < NV10A) { /* upto 32Mb RAM adressing: must be used this way on pre-NV10! */ /* set standard registers */ /* (NVidia: startadress in 32bit words (b2 - b17) */ vgaIO.setCRT(NVCRTCX_FBSTADDL, (startadd >> 2) & 0xFF); vgaIO.setCRT(NVCRTCX_FBSTADDH, (startadd >> 10) & 0xFF); /* set extended registers */ /* NV4 extended bits: (b18-22) */ int temp = vgaIO.getCRT(NVCRTCX_REPAINT0) & 0xE0; vgaIO.setCRT(NVCRTCX_REPAINT0, temp | ((startadd >> 18) & 0x1f)); /* NV4 extended bits: (b23-24) */ temp = vgaIO.getCRT(NVCRTCX_HEB) & 0xdf; vgaIO.setCRT(NVCRTCX_HEB, temp | ((startadd >> 18) & 0x20)); // temp = (CRTCR(HEB) & 0x9f); // CRTCW(HEB, (temp | ((startadd & 0x01800000) >> 18))); } else { /* upto 4Gb RAM adressing: must be used on NV10 and later! */ /* * NOTE: While this register also exists on pre-NV10 cards, it will * wrap-around at 16Mb boundaries!! */ /* 30bit adress in 32bit words */ vgaIO.setReg32(NV32_NV10FBSTADD32, startadd & 0xfffffffc); } int temp = vgaIO.getATT(NVATBX_HORPIXPAN) & 0xf9; vgaIO.setATT(NVATBX_HORPIXPAN, temp | ((startadd & 3) << 1)); } /** * @see org.jnode.driver.video.Surface#drawAlphaRaster(java.awt.image.Raster, * java.awt.geom.AffineTransform, int, int, int, int, int, int, * java.awt.Color) */ public void drawAlphaRaster(Raster raster, AffineTransform tx, int srcX, int srcY, int dstX, int dstY, int width, int height, Color color) { bitmapGraphics.drawAlphaRaster(raster, tx, srcX, srcY, dstX, dstY, width, height, convertColor(color)); } @Override public int getRGBPixel(int x, int y) { return bitmapGraphics.doGetPixel(x, y); } @Override public int[] getRGBPixels(Rectangle region) { return bitmapGraphics.doGetPixels(region); } }