nvidiacore.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 702 行 · 第 1/2 页
JAVA
702 行
/*
* $Id: NVidiaCore.java,v 1.5 2004/01/04 11:01:58 epr Exp $
*/
package org.jnode.driver.video.nvidia;
import java.awt.Color;
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.pci.PCIBaseAddress;
import org.jnode.driver.pci.PCIDevice;
import org.jnode.driver.pci.PCIDeviceConfig;
import org.jnode.driver.video.FrameBufferConfiguration;
import org.jnode.driver.video.ddc.DisplayDataChannelAPI;
import org.jnode.driver.video.util.AbstractSurface;
import org.jnode.driver.video.vgahw.DisplayMode;
import org.jnode.naming.InitialNaming;
import org.jnode.system.MemoryResource;
import org.jnode.system.ResourceManager;
import org.jnode.system.ResourceNotFreeException;
import org.jnode.util.NumberUtils;
import org.jnode.vm.Address;
/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
public class NVidiaCore extends AbstractSurface implements NVidiaConstants, DisplayDataChannelAPI {
/** My logger */
private final Logger log = Logger.getLogger(getClass());
private final NVidiaDriver driver;
private FrameBufferConfiguration config;
private final MemoryResource mmio;
private final MemoryResource videoRam;
private int bitsPerPixel = 32;
private int bytesPerLine;
private BitmapGraphics bitmapGraphics;
private final NVidiaVgaIO vgaIO;
private final NVidiaVgaState oldVgaState = new NVidiaVgaState();
private final int architecture;
/** Size of card memory in MB */
private final int memSize;
private final int DDCBase = 0x3e;
private final int CrystalFreqKHz;
private final int MaxVClockFreqKHz;
/** Hardware cursor implementation */
private final NVidiaHardwareCursor hwCursor;
/** Acceleration functions */
private final NVidiaAcceleration acc;
/** Should acceleration be used */
private final boolean useAcc = true;
/**
* @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 PCIDeviceConfig pciCfg = device.getConfig();
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 = (ResourceManager) 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.valueOf(ioBase), ioSize, ResourceManager.MEMMODE_NORMAL);
this.videoRam = rm.claimMemoryResource(device, Address.valueOf(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();
switch (architecture) {
case NV04A :
{
final int bootInfo = vgaIO.getReg32(NV32_NVSTRAPINFO2);
CrystalFreqKHz = ((bootInfo & 0x00000040) != 0) ? 14318 : 13500;
MaxVClockFreqKHz = 250000;
}
break;
case NV10A :
{
final int bootInfo = vgaIO.getReg32(NV32_NVSTRAPINFO2);
CrystalFreqKHz = ((bootInfo & 0x00000040) != 0) ? 14318 : 13500;
MaxVClockFreqKHz = 350000;
}
break;
default :
throw new DriverException("Unknown architecture " + architecture);
}
log.debug("Memory size =" + memSize + "MB");
log.debug("CrystalFreqKHz =" + CrystalFreqKHz);
log.debug("MaxVClockFreqKHz=" + MaxVClockFreqKHz);
}
/**
* 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 NVidiaDpmsState dpmsState = getDpms();
//log.debug("Old DPMS state: " + dpmsState);
setDpms(NVidiaDpmsState.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);
}
/**
* Close the SVGA screen
*
* @see org.jnode.driver.video.Surface#close()
*/
public synchronized void close() {
hwCursor.closeCursor();
final NVidiaDpmsState dpmsState = getDpms();
//log.debug("Old DPMS state: " + dpmsState);
setDpms(NVidiaDpmsState.OFF);
vgaIO.unlock();
oldVgaState.restoreToVGA(vgaIO);
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();
}
/**
* Release all resources
*/
final void release() {
mmio.release();
videoRam.release();
}
/**
* @see org.jnode.driver.video.util.AbstractSurface#convertColor(java.awt.Color)
*/
protected int convertColor(Color color) {
return color.getRGB();
}
/**
* @see org.jnode.driver.video.util.AbstractSurface#drawPixel(int, int, int, int)
*/
protected final void drawPixel(int x, int y, int color, int mode) {
bitmapGraphics.drawPixels(x, y, 1, color, mode);
}
/**
* @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.Surface#getColorModel()
*/
public ColorModel getColorModel() {
return config.getColorModel();
}
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));
}
/**
* 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));
}
/**
* 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;
}
private void setDpms(NVidiaDpmsState 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);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?