📄 vgacard.java
字号:
this.lastWidth = width; this.lastHeight = height; this.lastCH = charHeight; this.lastCW = charWidth; fullUpdate = true; } int curCursorOffset = ((crtRegister[CR_INDEX_CURSOR_LOC_HIGH] << 8) | crtRegister[CR_INDEX_CURSOR_LOC_LOW]) - this.startAddress; if ((curCursorOffset != this.cursorOffset) || (crtRegister[CR_INDEX_CURSOR_START] != this.cursorStart) || (crtRegister[CR_INDEX_CURSOR_END] != this.cursorEnd)) { /* if the cursor position changed, we updated the old and new chars */ if ((this.cursorOffset < CH_ATTR_SIZE) && (this.cursorOffset >= 0)) this.lastChar[this.cursorOffset] = -1; if ((curCursorOffset < CH_ATTR_SIZE) && (curCursorOffset >= 0)) this.lastChar[curCursorOffset] = -1; this.cursorOffset = curCursorOffset; this.cursorStart = crtRegister[CR_INDEX_CURSOR_START]; this.cursorEnd = crtRegister[CR_INDEX_CURSOR_END]; } int cursorIndex = (this.startAddress + this.cursorOffset) * 4; int lastCharOffset = 0; switch (charWidth) { case 8: for (int charY = 0; charY < height; charY++) { int srcOffset = srcIndex; for (int charX = 0; charX < width; charX++) { int charShort = 0xffff & ioRegion.getWord(srcOffset); if (fullUpdate || (charShort != this.lastChar[lastCharOffset])) { this.lastChar[lastCharOffset] = charShort; int character = 0xff & charShort; int characterAttribute = charShort >>> 8; int glyphOffset = fontOffset[(characterAttribute >>> 3) & 1] + 32 * 4 * character; int backgroundColor = palette[characterAttribute >>> 4]; int foregroundColor = palette[characterAttribute & 0xf]; drawGlyph8(device.getDisplayBuffer(), charY * charHeight * lastScreenWidth + charX * 8, lastScreenWidth, glyphOffset, charHeight, foregroundColor, backgroundColor); device.dirtyDisplayRegion(charX * 8, charY * charHeight, 8, charHeight); if ((srcOffset == cursorIndex) && ((crtRegister[CR_INDEX_CURSOR_START] & 0x20) == 0)) { int lineStart = crtRegister[CR_INDEX_CURSOR_START] & 0x1f; int lineLast = crtRegister[CR_INDEX_CURSOR_END] & 0x1f; /* XXX: check that */ if (lineLast > charHeight - 1) lineLast = charHeight - 1; if ((lineLast >= lineStart) && (lineStart < charHeight)) { int tempHeight = lineLast - lineStart + 1; drawCursorGlyph8(device.getDisplayBuffer(), (charY * charHeight + lineStart) * lastScreenWidth + charX * 8, lastScreenWidth, tempHeight, foregroundColor, backgroundColor); device.dirtyDisplayRegion(charX * 8, charY * charHeight + lineStart, 8, tempHeight); } } } srcOffset += 4; lastCharOffset++; } srcIndex += lineOffset; } return; case 9: for (int charY = 0; charY < height; charY++) { int srcOffset = srcIndex; for (int charX = 0; charX < width; charX++) { int charShort = 0xffff & ioRegion.getWord(srcOffset); if (fullUpdate || (charShort != this.lastChar[lastCharOffset])) { this.lastChar[lastCharOffset] = charShort; int character = 0xff & charShort; int characterAttribute = charShort >>> 8; int glyphOffset = fontOffset[(characterAttribute >>> 3) & 1] + 32 * 4 * character; int backgroundColor = palette[characterAttribute >>> 4]; int foregroundColor = palette[characterAttribute & 0xf]; boolean dup9 = ((character >= 0xb0) && (character <= 0xdf) && ((attributeRegister[AR_INDEX_ATTR_MODE_CONTROL] & 0x04) != 0)); drawGlyph9(device.getDisplayBuffer(), charY * charHeight * lastScreenWidth + charX * 9, lastScreenWidth, glyphOffset, charHeight, foregroundColor, backgroundColor, dup9); device.dirtyDisplayRegion(charX * 9, charY * charHeight, 9, charHeight); if ((srcOffset == cursorIndex) &&((crtRegister[CR_INDEX_CURSOR_START] & 0x20) == 0)) { int lineStart = crtRegister[CR_INDEX_CURSOR_START] & 0x1f; int lineLast = crtRegister[CR_INDEX_CURSOR_END] & 0x1f; /* XXX: check that */ if (lineLast > charHeight - 1) lineLast = charHeight - 1; if ((lineLast >= lineStart) && (lineStart < charHeight)) { int tempHeight = lineLast - lineStart + 1; drawCursorGlyph9(device.getDisplayBuffer(), (charY * charHeight + lineStart) * lastScreenWidth + charX * 9, lastScreenWidth, tempHeight, foregroundColor, backgroundColor); device.dirtyDisplayRegion(charX * 9, charY * charHeight + lineStart, 9, tempHeight); } } } srcOffset += 4; lastCharOffset++; } srcIndex += lineOffset; } return; case 16: for (int charY = 0; charY < height; charY++) { int srcOffset = srcIndex; for (int charX = 0; charX < width; charX++) { int charShort = 0xffff & ioRegion.getWord(srcOffset); if (fullUpdate || (charShort != this.lastChar[lastCharOffset])) { this.lastChar[lastCharOffset] = charShort; int character = 0xff & charShort; int characterAttribute = charShort >>> 8; int glyphOffset = fontOffset[(characterAttribute >>> 3) & 1] + 32 * 4 * character; int backgroundColor = palette[characterAttribute >>> 4]; int foregroundColor = palette[characterAttribute & 0xf]; drawGlyph16(device.getDisplayBuffer(), charY * charHeight * lastScreenWidth + charX * 16, lastScreenWidth, glyphOffset, charHeight, foregroundColor, backgroundColor); device.dirtyDisplayRegion(charX * 16, charY * charHeight, 16, charHeight); if ((srcOffset == cursorIndex) &&((crtRegister[CR_INDEX_CURSOR_START] & 0x20) == 0)) { int lineStart = crtRegister[CR_INDEX_CURSOR_START] & 0x1f; int lineLast = crtRegister[CR_INDEX_CURSOR_END] & 0x1f; /* XXX: check that */ if (lineLast > charHeight - 1) lineLast = charHeight - 1; if ((lineLast >= lineStart) && (lineStart < charHeight)) { int tempHeight = lineLast - lineStart + 1; drawCursorGlyph16(device.getDisplayBuffer(), (charY * charHeight + lineStart) * lastScreenWidth + charX * 16, lastScreenWidth, tempHeight, foregroundColor, backgroundColor); device.dirtyDisplayRegion(charX * 16, charY * charHeight + lineStart, 16, tempHeight); } } } srcOffset += 4; lastCharOffset++; } srcIndex += lineOffset; } return; default: System.err.println("Unknown Character Width: " + charWidth); return; } } abstract class GraphicsUpdater { int[] ex4; int[] ex2; GraphicsUpdater() { ex2 = new int[expand2.length]; System.arraycopy(expand2, 0, ex2, 0, ex2.length); ex4 = new int[expand4.length]; System.arraycopy(expand4, 0, ex4, 0, ex4.length); } abstract int byteWidth(int width); abstract void drawLine(GraphicsDisplay device, int offset, int width, int y, int dispWidth); public void dumpState(DataOutput output) throws IOException { output.writeInt(ex4.length); for (int i=0; i< ex4.length; i++) output.writeInt(ex4[i]); output.writeInt(ex2.length); for (int i=0; i< ex2.length; i++) output.writeInt(ex2[i]); } public void loadState(DataInput input) throws IOException { int len = input.readInt(); ex4 = new int[len]; for (int i=0; i< len; i++) ex4[i] = input.readInt(); len = input.readInt(); ex2 = new int[len]; for (int i=0; i< len; i++) ex2[i] = input.readInt(); } void updateDisplay(GraphicsDisplay device, int width, int height, int dispWidth, boolean fullUpdate, int multiScan) { int multiRun = multiScan; int addr1 = 4 * startAddress; //int lineSize = width; // get the line size from the display device?? // if the "cursor_invalidate" function pointer is not null, then call it here. //if (s->cursor_invalidate) //s->cursor_invalidate(s); int y1 = 0; boolean addrMunge1 = (crtRegister[CR_INDEX_CRTC_MODE_CONTROL] & 1) == 0; boolean addrMunge2 = (crtRegister[CR_INDEX_CRTC_MODE_CONTROL] & 2) == 0; boolean addrMunge = addrMunge1 || addrMunge2; int mask = (crtRegister[CR_INDEX_CRTC_MODE_CONTROL] & 3) ^ 3; int pageMin = Integer.MAX_VALUE; int pageMax = Integer.MIN_VALUE; for(int y = 0; y < height; y++) { boolean update = fullUpdate; int addr = addr1; if (addrMunge) { if (addrMunge1) { /* CGA compatibility handling */ int shift = 14 + ((crtRegister[CR_INDEX_CRTC_MODE_CONTROL] >>> 6) & 1); addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift); } if (addrMunge2) addr = (addr & ~0x8000) | ((y1 & 2) << 14); } int pageStart = addr >>> PAGE_SHIFT; int pageEnd = (addr + byteWidth(width) - 1) >>> PAGE_SHIFT; for (int i = pageStart; i <= pageEnd; i++) { if (update |= ioRegion.pageIsDirty(i)) { pageMin = Math.min(pageMin, pageStart); pageMax = Math.max(pageMax, pageEnd); drawLine(device, addr, width, y, dispWidth); // if the "cursor_draw_line" function pointer is not null, then call it here. //if (s->cursor_draw_line) // s->cursor_draw_line(s, d, y); break; } } if (multiRun == 0) { if ((y1 & mask) == mask) addr1 += lineOffset; y1++; multiRun = multiScan; } else multiRun--; /* line compare acts on the displayed lines */ if (y == lineCompare) addr1 = 0; } for (int i = pageMin; i <= pageMax; i++) ioRegion.cleanPage(i); } } class DrawLine2 extends GraphicsUpdater { int byteWidth(int width) { return (width / 2); } void drawLine(GraphicsDisplay device, int offset, int width, int y, int dispWidth) { int[] dest = device.getDisplayBuffer(); int index = y * dispWidth; int[] palette = lastPalette; int planeMask = mask16[attributeRegister[AR_INDEX_COLOR_PLANE_ENABLE] & 0xf]; width >>>= 3; do { int data = ioRegion.getDoubleWord(offset); data &= planeMask; int v = ex2[data & 0xff]; v |= ex2[(data >>> 16) & 0xff] << 2; dest[index++] = palette[v >>> 12]; dest[index++] = palette[(v >>> 8) & 0xf]; dest[index++] = palette[(v >>> 4) & 0xf]; dest[index++] = palette[(v >>> 0) & 0xf]; v = ex2[(data >>> 8) & 0xff]; v |= ex2[(data >>> 24) & 0xff] << 2; dest[index++] = palette[v >>> 12]; dest[index++] = palette[(v >>> 8) & 0xf]; dest[index++] = palette[(v >>> 4) & 0xf]; dest[index++] = palette[(v >>> 0) & 0xf]; offset += 4; } while (--width != 0); device.dirtyDisplayRegion(0, y, dispWidth, 1); } } class DrawLine2d2 extends GraphicsUpdater { int byteWidth(int width) { return (width/2); } void drawLine(GraphicsDisplay device, int offset, int width, int y, int dispWidth) { int[] dest = device.getDisplayBuffer(); int index = y * dispWidth; int[] palette = lastPalette; int planeMask = mask16[attributeRegister[AR_INDEX_COLOR_PLANE_ENABLE] & 0xf]; width >>>= 3; do { int data = ioRegion.getDoubleWord(offset); data &= planeMask; int v = ex2[data & 0xff]; v |= ex2[(data >>> 16) & 0xff] << 2; dest[index++] = dest[index++] = palette[v >>> 12]; dest[index++] = dest[index++] = palette[(v >>> 8) & 0xf]; dest[index++] = dest[index++] = palette[(v >>> 4) & 0xf]; dest[index++] = dest[index++] = palette[(v >>> 0) & 0xf]; v = ex2[(data >>> 8) & 0xff]; v |= ex2[(data >>> 24) & 0xff] << 2; dest[index++] = dest[index++] = palette[v >>> 12]; dest[index++] = dest[index++] = palette[(v >>> 8) & 0xf]; dest[index++] = dest[index++] = palette[(v >>> 4) & 0xf]; dest[index++] = dest[index++] = palette[(v >>> 0) & 0xf]; offset += 4; } while (--width != 0); device.dirtyDisplayRegion(0, y, dispWidth, 1); } } class DrawLine4 extends GraphicsUpdater { int byteWidth(int width) { return (width/2); } void drawLine(GraphicsDisplay device, int offset, int width, int y, int dispWidth) { int[] dest = device.getDisplayBuffer(); int index = y * dispWidth; int[] palette = lastPalette; int planeMask = mask16[attributeRegister[AR_INDEX_COLOR_PLANE_ENABLE] & 0xf]; width >>>= 3; do { int data = ioRegion.getDoubleWord(offset) & planeMask; int v = ex4[data & 0xff]; data >>>= 8; v |= ex4[data & 0xff] << 1; data >>>= 8; v |= ex4[data & 0xff] << 2; data >>>= 8; v |= ex4[data & 0xff] << 3; dest[index++] = palette[v >>> 28]; dest[index++] = palette[(v >>> 24) & 0xF]; dest[index++] = palette[(v >>> 20) & 0xF]; dest[index++] = palette[(v >>> 16) & 0xF]; dest[index++] = palette[(v >>> 12) & 0xF]; dest[index++] = palette[(v >>> 8) & 0xF]; dest[index++] = palette[(v >>> 4) & 0xF]; dest[index++] = palette[(v >>> 0) & 0xF]; offset += 4; } while (--width != 0); device.dirtyDisplayRegion(0, y, dispWidth , 1); } } class DrawLine4d2 extends GraphicsUpdater { int byteWidth(int width) { return (width/2); } void drawLine(GraphicsDisplay device, int offset, int width, int y, int dispWidth) { int[] dest = device.getDisplayBuffer(); int index = y * dispWidth; int[] palette = lastPalette; int planeMask = mask16[attributeRegister[AR_INDEX_COLOR_PLANE_ENABLE] & 0xf]; width >>>= 3; do { int data = ioRegion.getDoubleWord(offset); data &= planeMask; int v = ex4[data & 0xff]; v |= ex4[(data >>> 8) & 0xff] << 1; v |= ex4[(data >>> 16) & 0xff] << 2; v |= ex4[(data >>> 24) & 0xff] << 3; dest[index++] = dest[index++] = palette[v >>> 28]; dest[index++] = dest[index++] = palette[(v >>> 24) & 0xF]; dest[index++] = dest[index++] = palette[(v >>> 20) & 0xF]; dest[index++] = dest[index++] = palette[(v >>> 16) & 0xF];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -