📄 vgacard.java
字号:
{ setByte(offset++, (byte)data); data >>>= 8; setByte(offset, (byte)data); } public void setDoubleWord(int offset, int data) { setByte(offset++, (byte)data); data >>>= 8; setByte(offset++, (byte)data); data >>>= 8; setByte(offset++, (byte)data); data >>>= 8; setByte(offset, (byte)data); } public void setQuadWord(int offset, long data) { setDoubleWord(offset, (int) data); setDoubleWord(offset+4, (int) (data >> 32)); } public void setLowerDoubleQuadWord(int offset, long data) { setDoubleWord(offset, (int) data); setDoubleWord(offset+4, (int) (data >> 32)); } public void setUpperDoubleQuadWord(int offset, long data) { offset += 8; setDoubleWord(offset, (int) data); setDoubleWord(offset+4, (int) (data >> 32)); } public void clear() { internalReset(); } public void clear(int start, int length) { clear(); } public int execute(Processor cpu, int offset) { throw new IllegalStateException("Invalid Operation"); } public CodeBlock decodeCodeBlockAt(Processor cpu, int offset) { throw new IllegalStateException("Invalid Operation"); } } public static class VGARAMIORegion extends MemoryMappedIORegion { private byte[] buffer; private int startAddress; private boolean[] dirtyPages; public VGARAMIORegion() { // buffer = new byte[VGA_RAM_SIZE]; buffer = new byte[INIT_VGA_RAM_SIZE]; dirtyPages = new boolean[(VGA_RAM_SIZE >>> PAGE_SHIFT) + 1]; for (int i = 0; i < dirtyPages.length; i++) dirtyPages[i] = false; startAddress = -1; } public void dumpState(DataOutput output) throws IOException { output.writeInt(startAddress); output.writeInt(buffer.length); output.write(buffer); output.writeInt(dirtyPages.length); for (int i=0; i< dirtyPages.length; i++) output.writeBoolean(dirtyPages[i]); } public void loadState(DataInput input) throws IOException { startAddress = input.readInt(); int len = input.readInt(); buffer = new byte[len]; input.readFully(buffer,0,len); len = input.readInt(); dirtyPages = new boolean[len]; for (int i = 0; i < len; i++) dirtyPages[i] = input.readBoolean(); } private void increaseVGARAMSize(int offset) { if ((offset < 0) || (offset >= VGA_RAM_SIZE)) throw new ArrayIndexOutOfBoundsException("tried to access outside of memeory bounds"); int newSize = buffer.length; while (newSize <= offset) newSize = newSize << 1; if (newSize > VGA_RAM_SIZE) newSize = VGA_RAM_SIZE; byte[] newBuf = new byte[newSize]; System.arraycopy(buffer, 0, newBuf, 0, buffer.length); buffer = newBuf; } public void copyContentsInto(int address, byte[] buf, int off, int len) { System.out.println("address = " + address + ". offset = " + off + ". len = " + len + ". buffer.length = " + buffer.length); System.arraycopy(buffer, address, buf, off, len); } public void copyContentsFrom(int address, byte[] buf, int off, int len) { System.arraycopy(buf, off, buffer, address, len); } public void clear() { for (int i = 0; i < buffer.length; i++) buffer[i] = 0; for (int i = 0; i < dirtyPages.length; i++) dirtyPages[i] = false; } public void clear(int start, int length) { int limit = start + length; if (limit > getSize()) throw new ArrayIndexOutOfBoundsException("Attempt to clear outside of memory bounds"); try { for (int i = start; i < limit; i++) buffer[i] = 0; } catch (ArrayIndexOutOfBoundsException e) {} int pageStart = start >>> PAGE_SHIFT; int pageLimit = (limit - 1) >>> PAGE_SHIFT; for (int i = pageStart; i <= pageLimit; i++) dirtyPages[i] = true; } public boolean isCacheable() { return false; } public boolean isVolatile() { return false; } public boolean pageIsDirty(int i) { return dirtyPages[i]; } public void cleanPage(int i) { dirtyPages[i] = false; } //IORegion Methods public int getAddress() { return startAddress; } public long getSize() { return VGA_RAM_SIZE; } public int getType() { return PCI_ADDRESS_SPACE_MEM_PREFETCH; } public int getRegionNumber() { return 0; } public void setAddress(int address) { this.startAddress = address; } public void setByte(int offset, byte data) { try { dirtyPages[offset >>> PAGE_SHIFT] = true; buffer[offset] = data; } catch (ArrayIndexOutOfBoundsException e) { increaseVGARAMSize(offset); setByte(offset, data); } } public byte getByte(int offset) { try { return buffer[offset]; } catch (ArrayIndexOutOfBoundsException e) { increaseVGARAMSize(offset); return getByte(offset); } } public void setWord(int offset, short data) { try { buffer[offset] = (byte) data; dirtyPages[offset >>> PAGE_SHIFT] = true; offset++; buffer[offset] = (byte) (data >> 8); dirtyPages[offset >>> PAGE_SHIFT] = true; } catch (ArrayIndexOutOfBoundsException e) { increaseVGARAMSize(offset); setWord(offset, data); } } public short getWord(int offset) { try { int result = 0xFF & buffer[offset]; offset++; result |= buffer[offset] << 8; return (short) result; } catch (ArrayIndexOutOfBoundsException e) { increaseVGARAMSize(offset); return getWord(offset); } } public void setDoubleWord(int offset, int data) { try { dirtyPages[offset >>> PAGE_SHIFT] = true; buffer[offset] = (byte) data; offset++; data >>= 8; buffer[offset] = (byte) (data); offset++; data >>= 8; buffer[offset] = (byte) (data); offset++; data >>= 8; buffer[offset] = (byte) (data); dirtyPages[offset >>> PAGE_SHIFT] = true; } catch (ArrayIndexOutOfBoundsException e) { increaseVGARAMSize(offset); setDoubleWord(offset, data); } } public int getDoubleWord(int offset) { try { int result= 0xFF & buffer[offset]; offset++; result |= (0xFF & buffer[offset]) << 8; offset++; result |= (0xFF & buffer[offset]) << 16; offset++; result |= (buffer[offset]) << 24; return result; } catch (ArrayIndexOutOfBoundsException e) { increaseVGARAMSize(offset); return getDoubleWord(offset); } } public String toString() { return "VGA RAM ByteArray["+getSize()+"]"; } public int execute(Processor cpu, int offset) { throw new IllegalStateException("Invalid Operation"); } public CodeBlock decodeCodeBlockAt(Processor cpu, int offset) { throw new IllegalStateException("Invalid Operation"); } } //Public Methods Used By Output Device public final void updateDisplay(GraphicsDisplay device) { if (device == null) return; updatingScreen = true; boolean fullUpdate = false; int detGraphicMode; if ((attributeRegisterIndex & 0x20) == 0) detGraphicMode = GMODE_BLANK; else detGraphicMode = graphicsRegister[GR_INDEX_MISC] & 1; if (detGraphicMode != this.graphicMode) { this.graphicMode = detGraphicMode; fullUpdate = true; } switch(graphicMode) { case GMODE_TEXT: drawText(fullUpdate, device); break; case GMODE_GRAPH: drawGraphic(fullUpdate, device); break; case GMODE_BLANK: default: drawBlank(fullUpdate, device); break; } updatingScreen = false; } private final void drawText(boolean fullUpdate, GraphicsDisplay device) { boolean temp = updatePalette16(device); fullUpdate |= temp; int[] palette = lastPalette; /* compute font data address (in plane 2) */ int v = this.sequencerRegister[SR_INDEX_CHAR_MAP_SELECT]; int offset = (((v >>> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2; if (offset != this.fontOffset[0]) { this.fontOffset[0] = offset; fullUpdate = true; } offset = (((v >>> 5) & 1) | ((v >>> 1) & 6)) * 8192 * 4 + 2; if (offset != this.fontOffset[1]) { this.fontOffset[1] = offset; fullUpdate = true; } if ((this.planeUpdated & (1 << 2)) != 0) { /* if the plane 2 was modified since the last display, it indicates the font may have been modified */ this.planeUpdated = 0; fullUpdate = true; } temp = updateBasicParameters(); fullUpdate |= temp; int srcIndex = this.startAddress * 4; /* total width and height */ int charHeight = (crtRegister[CR_INDEX_MAX_SCANLINE] & 0x1f) + 1; int charWidth = 8; if ((sequencerRegister[SR_INDEX_CLOCKING_MODE] & 0x01) == 0) charWidth = 9; if ((sequencerRegister[SR_INDEX_CLOCKING_MODE] & 0x08) != 0) charWidth = 16; /* NOTE: no 18 pixel wide */ int width = crtRegister[CR_INDEX_HORZ_DISPLAY_END] + 1; int height; if (crtRegister[CR_INDEX_VERT_TOTAL] == 100) { /* ugly hack for CGA 160x100x16 */ height = 100; } else { height = crtRegister[CR_INDEX_VERT_DISPLAY_END] | ((crtRegister[CR_INDEX_OVERFLOW] & 0x02) << 7) | ((crtRegister[CR_INDEX_OVERFLOW] & 0x40) << 3); height = (height + 1) / charHeight; } if ((height * width) > CH_ATTR_SIZE) { /* better than nothing: exit if transient size is too big */ return; } if ((width != this.lastWidth) || (height != this.lastHeight) || (charWidth != this.lastCW) || (charHeight != this.lastCH)) { this.lastScreenWidth = width * charWidth; this.lastScreenHeight = height * charHeight; device.resizeDisplay(this.lastScreenWidth, this.lastScreenHeight);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -