📄 vgacard.java
字号:
} 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 + -