⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vgacard.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    }    private final void vbeIOPortWriteData(int data)    {	if (vbeIndex <= VBE_DISPI_INDEX_NB) {	    switch(vbeIndex) {	    case VBE_DISPI_INDEX_ID:		if (data == VBE_DISPI_ID0 || data == VBE_DISPI_ID1 || data == VBE_DISPI_ID2)		    vbeRegs[vbeIndex] = data;		break;	    case VBE_DISPI_INDEX_XRES:		if ((data <= VBE_DISPI_MAX_XRES) && ((data & 7) == 0))		    vbeRegs[vbeIndex] = data;		break;	    case VBE_DISPI_INDEX_YRES:		if (data <= VBE_DISPI_MAX_YRES)		    vbeRegs[vbeIndex] = data;		break;	    case VBE_DISPI_INDEX_BPP:		if (data == 0)		    data = 8;		if (data == 4 || data == 8 || data == 15 ||		    data == 16 || data == 24 || data == 32) {		    vbeRegs[vbeIndex] = data;		}		break;	    case VBE_DISPI_INDEX_BANK:		data &= vbeBankMask;		vbeRegs[vbeIndex] = data;		bankOffset = data << 16;		break;	    case VBE_DISPI_INDEX_ENABLE:		if ((data & VBE_DISPI_ENABLED) != 0) {		    vbeRegs[VBE_DISPI_INDEX_VIRT_WIDTH] = vbeRegs[VBE_DISPI_INDEX_XRES];		    vbeRegs[VBE_DISPI_INDEX_VIRT_HEIGHT] = vbeRegs[VBE_DISPI_INDEX_YRES];		    vbeRegs[VBE_DISPI_INDEX_X_OFFSET] = 0;		    vbeRegs[VBE_DISPI_INDEX_Y_OFFSET] = 0;		    if (vbeRegs[VBE_DISPI_INDEX_BPP] == 4)			vbeLineOffset = vbeRegs[VBE_DISPI_INDEX_XRES] >>> 1;		    else			vbeLineOffset = vbeRegs[VBE_DISPI_INDEX_XRES] * ((vbeRegs[VBE_DISPI_INDEX_BPP] + 7) >>> 3);		    vbeStartAddress = 0;		    /* clear the screen (should be done in BIOS) */		    if ((data & VBE_DISPI_NOCLEARMEM) == 0)                     {                        int limit = vbeRegs[VBE_DISPI_INDEX_YRES] * vbeLineOffset;                        for (int i=0; i<limit; i++)                            ioRegion.setByte(i, (byte) 0);		    }		    /* we initialise the VGA graphic mode */		    /* (should be done in BIOS) */		    /* graphic mode + memory map 1 */		    graphicsRegister[GR_INDEX_MISC] = (graphicsRegister[GR_INDEX_MISC] & ~0x0c) | 0x05;		    crtRegister[CR_INDEX_CRTC_MODE_CONTROL] |= 0x3; /* no CGA modes */		    crtRegister[CR_INDEX_OFFSET] = (vbeLineOffset >>> 3);		    /* width */		    crtRegister[CR_INDEX_HORZ_DISPLAY_END] = (vbeRegs[VBE_DISPI_INDEX_XRES] >>> 3) - 1;		    /* height */		    int h = vbeRegs[VBE_DISPI_INDEX_YRES] - 1;		    crtRegister[CR_INDEX_VERT_DISPLAY_END] = h;		    crtRegister[CR_INDEX_OVERFLOW] = (crtRegister[CR_INDEX_OVERFLOW] & ~0x42) | ((h >>> 7) & 0x02) | ((h >>> 3) & 0x40);		    /* line compare to 1023 */		    crtRegister[CR_INDEX_LINE_COMPARE] = 0xff;		    crtRegister[CR_INDEX_OVERFLOW] |= 0x10;		    crtRegister[CR_INDEX_MAX_SCANLINE] |= 0x40;		    int shiftControl;		    if (vbeRegs[VBE_DISPI_INDEX_BPP] == 4) {			shiftControl = 0;			sequencerRegister[SR_INDEX_CLOCKING_MODE] &= ~0x8; /* no double line */		    } else {			shiftControl = 2;			sequencerRegister[SR_INDEX_SEQ_MEMORY_MODE] |= 0x08; /* set chain 4 mode */			sequencerRegister[SR_INDEX_MAP_MASK] |= 0x0f; /* activate all planes */		    }		    graphicsRegister[GR_INDEX_GRAPHICS_MODE] = (graphicsRegister[GR_INDEX_GRAPHICS_MODE] & ~0x60) | (shiftControl << 5);		    crtRegister[CR_INDEX_MAX_SCANLINE] &= ~0x9f; /* no double scan */		} else {		    /* XXX: the bios should do that */		    bankOffset = 0;		}		vbeRegs[vbeIndex] = data;		break;	    case VBE_DISPI_INDEX_VIRT_WIDTH:		{		    if (data < vbeRegs[VBE_DISPI_INDEX_XRES])			return;		    int w = data;		    int lineOffset;		    if (vbeRegs[VBE_DISPI_INDEX_BPP] == 4) {			lineOffset = data >>> 1;		    } else {			lineOffset = data * ((vbeRegs[VBE_DISPI_INDEX_BPP] + 7) >>> 3);		    }		    int h = VGA_RAM_SIZE / lineOffset;		    /* XXX: support wierd bochs semantics ? */		    if (h < vbeRegs[VBE_DISPI_INDEX_YRES])			return;		    vbeRegs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;		    vbeRegs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;		    vbeLineOffset = lineOffset;		}		break;	    case VBE_DISPI_INDEX_X_OFFSET:	    case VBE_DISPI_INDEX_Y_OFFSET:		{		    vbeRegs[vbeIndex] = data;		    vbeStartAddress = vbeLineOffset * vbeRegs[VBE_DISPI_INDEX_Y_OFFSET];		    int x = vbeRegs[VBE_DISPI_INDEX_X_OFFSET];		    if (vbeRegs[VBE_DISPI_INDEX_BPP] == 4) {			vbeStartAddress += x >>> 1;		    } else {			vbeStartAddress += x * ((vbeRegs[VBE_DISPI_INDEX_BPP] + 7) >>> 3);		    }		    vbeStartAddress >>>= 2;		}		break;	    default:		break;	    }	}    }    private final int vbeIOPortReadIndex()    {	return vbeIndex;    }    private final int vbeIOPortReadData()    {	if (vbeIndex <= VBE_DISPI_INDEX_NB) {	    return vbeRegs[vbeIndex];	} else {	    return 0;	}    }    private final void internalReset()    {	latch = 0;	sequencerRegisterIndex = graphicsRegisterIndex = attributeRegisterIndex = crtRegisterIndex = 0;    	attributeRegisterFlipFlop = false;	miscellaneousOutputRegister = 0;	featureControlRegister = 0;	st00 = st01 = 0; // status 0 and 1	dacState = dacSubIndex = dacReadIndex = dacWriteIndex = 0;        shiftControl = doubleScan = 0;	bankOffset = 0;	vbeIndex = 0;	vbeStartAddress = 0;	vbeLineOffset = 0;	vbeBankMask = 0;	graphicMode = 0;	lineOffset = 0;	lineCompare = 0;	startAddress = 0;	planeUpdated = 0;	lastCW = lastCH = 0;	lastWidth = lastHeight = 0;	lastScreenWidth = lastScreenHeight = 0;	cursorStart = cursorEnd = 0;	cursorOffset = 0;//         for (int i=0; i<lastPalette.length; i++)//             lastPalette[i] = new int[256];        ByteBuffer.fillIntArray(lastChar, 0);        ByteBuffer.fillIntArray(fontOffset, 0);        ByteBuffer.fillIntArray(vbeRegs, 0);        ByteBuffer.fillIntArray(dacCache, 0);        ByteBuffer.fillIntArray(palette, 0);        ByteBuffer.fillIntArray(sequencerRegister, 0);        ByteBuffer.fillIntArray(graphicsRegister, 0);        ByteBuffer.fillIntArray(attributeRegister, 0);        ByteBuffer.fillIntArray(crtRegister, 0);	graphicMode = -1;    }    public class VGALowMemoryRegion extends Memory    {	public boolean isCacheable() {return false;}	public boolean isVolatile() {return true;}	public void copyContentsInto(int address, byte[] buffer, int off, int len) {	    throw new IllegalStateException("copyContentsInto: Invalid Operation for VGA Card");	}	public void copyContentsFrom(int address, byte[] buffer, int off, int len) {	    throw new IllegalStateException("copyContentsFrom: Invalid Operation for VGA Card");	}	public long getSize()	{	    return 0x20000;	}	        public boolean isAllocated()        {            return false;        }	public byte getByte(int offset)	{	    /* convert to VGA memory offset */	    int memoryMapMode = (graphicsRegister[GR_INDEX_MISC] >>> 2) & 3;	    offset &= 0x1ffff;	    switch (memoryMapMode) {	    case 0:		break;	    case 1:		if (offset >= 0x10000)		    return (byte) 0xff;		offset += bankOffset;		break;	    case 2:		offset -= 0x10000;		if ((offset >= 0x8000) || (offset < 0))		    return (byte) 0xff;		break;	    default:	    case 3:		offset -= 0x18000;		if (offset < 0)		    return (byte) 0xff;		break;	    }	    	    if ((sequencerRegister[SR_INDEX_SEQ_MEMORY_MODE] & 0x08) != 0) {		/* chain 4 mode : simplest access */		//return vramPtr[address];		return ioRegion.getByte(offset);	    } else if ((graphicsRegister[GR_INDEX_GRAPHICS_MODE] & 0x10) != 0) {		/* odd/even mode (aka text mode mapping) */		int plane = (graphicsRegister[GR_INDEX_READ_MAP_SELECT] & 2) | (offset & 1);		return ioRegion.getByte(((offset & ~1) << 1) | plane);	    } else {		/* standard VGA latched access */		latch = ioRegion.getDoubleWord(4 * offset);				if ((graphicsRegister[GR_INDEX_GRAPHICS_MODE] & 0x08) == 0) {		    /* read mode 0 */		    return (byte)(latch >>> (graphicsRegister[GR_INDEX_READ_MAP_SELECT] * 8));		} else {		    /* read mode 1 */		    int ret = (latch ^ mask16[graphicsRegister[GR_INDEX_COLOR_COMPARE]])			& mask16[graphicsRegister[GR_INDEX_COLOR_DONT_CARE]];		    ret |= ret >>> 16;		    ret |= ret >>> 8;		    return (byte)(~ret);		}	    }	}		public short getWord(int offset)	{	    int v = 0xFF & getByte(offset);	    v |= getByte(offset + 1) << 8;	    return (short) v;	}		public int getDoubleWord(int offset)	{	    int v = 0xFF & getByte(offset);	    v |= (0xFF & getByte(offset + 1)) << 8;	    v |= (0xFF & getByte(offset + 2)) << 16;	    v |= (0xFF & getByte(offset + 3)) << 24;       	    return v;	}		public long getQuadWord(int offset)	{	    long v = 0xFFl & getByte(offset);	    v |= (0xFFl & getByte(offset + 1)) << 8;	    v |= (0xFFl & getByte(offset + 2)) << 16;	    v |= (0xFFl & getByte(offset + 3)) << 24; 	    v |= (0xFFl & getByte(offset + 4)) << 32; 	    v |= (0xFFl & getByte(offset + 5)) << 40; 	    v |= (0xFFl & getByte(offset + 6)) << 48; 	    v |= (0xFFl & getByte(offset + 7)) << 56;       	    return v;	}		public long getLowerDoubleQuadWord(int offset)	{	    return getQuadWord(offset);	}		public long getUpperDoubleQuadWord(int offset)	{	    return getQuadWord(offset+8);	}		public void setByte(int offset, byte data)	{	    /* convert to VGA memory offset */	    int memoryMapMode = (graphicsRegister[GR_INDEX_MISC] >>> 2) & 3;	    offset &= 0x1ffff;	    switch (memoryMapMode) {	    case 0:		break;	    case 1:		if (offset >= 0x10000)		    return;		offset += bankOffset;		break;	    case 2:		offset -= 0x10000;		if ((offset >= 0x8000) || (offset < 0))		    return;		break;	    default:	    case 3:		offset -= 0x18000;		//should be (unsigned) if (offset >= 0x8000) but anding above "offset &= 0x1ffff;" means <=> the below		if (offset < 0)		    return;		break;	    }	    	    if ((sequencerRegister[SR_INDEX_SEQ_MEMORY_MODE] & 0x08) != 0) {		/* chain 4 mode : simplest access */		int plane = offset & 3;		int mask = 1 << plane;		if ((sequencerRegister[SR_INDEX_MAP_MASK] & mask) != 0) {		    ioRegion.setByte(offset, data);		    planeUpdated |= mask; // only used to detect font change		    //cpu_physical_memory_set_dirty		}	    } else if ((graphicsRegister[GR_INDEX_GRAPHICS_MODE] & 0x10) != 0) {		/* odd/even mode (aka text mode mapping) */		int plane = (graphicsRegister[GR_INDEX_READ_MAP_SELECT] & 2) | (offset & 1);		int mask = 1 << plane;		if ((sequencerRegister[SR_INDEX_MAP_MASK] & mask) != 0) {		    ioRegion.setByte(((offset & ~1) << 1) | plane, data);		    planeUpdated |= mask; // only used to detect font change		    //cpu_physical_memory_set_dirty		}	    } else {		/* standard VGA latched access */		int bitMask = 0;		int writeMode = graphicsRegister[GR_INDEX_GRAPHICS_MODE] & 3;		int intData = 0xff & data;		switch (writeMode) {		default:		case 0:		    /* rotate */		    int b = graphicsRegister[GR_INDEX_DATA_ROTATE] & 7;		    intData |= intData << 8;		    intData |= intData << 16;		    intData = (intData >>> b) | (intData << -b);                    //Integer.rotateRight(intData, b);		    		    /* apply set/reset mask */		    int setMask = mask16[graphicsRegister[GR_INDEX_ENABLE_SETRESET]];		    intData = (intData & ~setMask) | (mask16[graphicsRegister[GR_INDEX_SETRESET]] & setMask);		    bitMask = graphicsRegister[GR_INDEX_BITMASK];		    break;		case 1:		    intData = latch;		    int mask = sequencerRegister[SR_INDEX_MAP_MASK];		    planeUpdated |= mask; // only used to detect font change		    int writeMask = mask16[mask];		    //check address being used here;		    offset <<= 2;		    ioRegion.setDoubleWord(offset, (ioRegion.getDoubleWord(offset) & ~writeMask) | (intData & writeMask));		    return;		case 2:		    intData = mask16[intData & 0x0f];		    bitMask = graphicsRegister[GR_INDEX_BITMASK];		    break;		case 3:		    /* rotate */		    b = graphicsRegister[GR_INDEX_DATA_ROTATE] & 7;		    intData = ((intData >>> b) | (intData << (8-b)));		    bitMask = graphicsRegister[GR_INDEX_BITMASK] & intData;		    intData = mask16[graphicsRegister[GR_INDEX_SETRESET]];		    break;		}				/* apply logical operation */		int funcSelect = graphicsRegister[GR_INDEX_DATA_ROTATE] >>> 3;		switch (funcSelect) {		default:		case 0:		    /* nothing to do */		    break;		case 1:		    /* and */		    intData &= latch;		    break;		case 2:		    /* or */		    intData |= latch;		    break;		case 3:		    /* xor */		    intData ^= latch;		    break;		}				/* apply bit mask */		bitMask |= bitMask << 8;		bitMask |= bitMask << 16;		intData = (intData & bitMask) | (latch & ~bitMask);				/* mask data according to sequencerRegister[SR_INDEX_MAP_MASK] */		int mask = sequencerRegister[SR_INDEX_MAP_MASK];		planeUpdated |= mask; // only used to detect font change		int writeMask = mask16[mask];		offset <<= 2;		//check address being used here;            		ioRegion.setDoubleWord(offset, (ioRegion.getDoubleWord(offset) & ~writeMask) | (intData & writeMask));	    }	}		public void setWord(int offset, short data)

⌨️ 快捷键说明

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