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

📄 serialport.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
字号:
/*    JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine    Release Version 2.0    A project from the Physics Dept, The University of Oxford    Copyright (C) 2007 Isis Innovation Limited    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License version 2 as published by    the Free Software Foundation.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License along    with this program; if not, write to the Free Software Foundation, Inc.,    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.     Details (including contact information) can be found at:     www.physics.ox.ac.uk/jpc*/package org.jpc.emulator.peripheral;import org.jpc.emulator.motherboard.*;import org.jpc.emulator.HardwareComponent;import java.io.*;/** * Emulates a standard 16450 UART. */public class SerialPort implements IOPortCapable, HardwareComponent{    private static final byte UART_LCR_DLAB = (byte)0x80; /* Divisor latch access bit */        private static final byte UART_IER_MSI = 0x08; /* Enable Modem status interrupt */    private static final byte UART_IER_RLSI = 0x04; /* Enable receiver line status interrupt */    private static final byte UART_IER_THRI = 0x02; /* Enable Transmitter holding register int. */    private static final byte UART_IER_RDI = 0x01; /* Enable receiver data interrupt */        private static final byte UART_IIR_NO_INT = 0x01; /* No interrupts pending */    private static final byte UART_IIR_ID = 0x06; /* Mask for the interrupt ID */        private static final byte UART_IIR_MSI = 0x00; /* Modem status interrupt */    private static final byte UART_IIR_THRI = 0x02; /* Transmitter holding register empty */    private static final byte UART_IIR_RDI = 0x04; /* Receiver data interrupt */    private static final byte UART_IIR_RLSI = 0x06; /* Receiver line status interrupt */    /*     * These are the definitions for the Modem Control Register     */    private static final byte UART_MCR_LOOP = 0x10; /* Enable loopback test mode */    private static final byte UART_MCR_OUT2 = 0x08; /* Out2 complement */    private static final byte UART_MCR_OUT1 = 0x04; /* Out1 complement */    private static final byte UART_MCR_RTS = 0x02; /* RTS complement */    private static final byte UART_MCR_DTR = 0x01; /* DTR complement */        /*     * These are the definitions for the Modem Status Register     */    private static final byte UART_MSR_DCD = (byte)0x80; /* Data Carrier Detect */    private static final byte UART_MSR_RI = 0x40; /* Ring Indicator */    private static final byte UART_MSR_DSR = 0x20; /* Data Set Ready */    private static final byte UART_MSR_CTS = 0x10; /* Clear to Send */    private static final byte UART_MSR_DDCD = 0x08; /* Delta DCD */    private static final byte UART_MSR_TERI = 0x04; /* Trailing edge ring indicator */    private static final byte UART_MSR_DDSR = 0x02; /* Delta DSR */    private static final byte UART_MSR_DCTS = 0x01; /* Delta CTS */    private static final byte UART_MSR_ANY_DELTA = 0x0F; /* Any of the delta bits! */        private static final byte UART_LSR_TEMT = 0x40; /* Transmitter empty */    private static final byte UART_LSR_THRE = 0x20; /* Transmit-hold-register empty */    private static final byte UART_LSR_BI = 0x10; /* Break interrupt indicator */    private static final byte UART_LSR_FE = 0x08; /* Frame error indicator */    private static final byte UART_LSR_PE = 0x04; /* Parity error indicator */    private static final byte UART_LSR_OE = 0x02; /* Overrun error indicator */    private static final byte UART_LSR_DR = 0x01; /* Receiver data ready */    private static final int[] ioPorts =	new int[]{0x3f8, 0x2f8, 0x3e8, 0x2e8};    private static final int[] irqLines = 	new int[]{4, 3, 4, 3};    private short divider;    private byte receiverBufferRegister; /* receiver buffer register */    private byte interruptEnableRegister; /* interrupt enable register */    private byte interruptIORegister; /* interrupt I/O register */ /* read only */    private byte lineControlRegister; /* line control register */    private byte lineStatusRegister; /* line status register */ /* read only */    private byte modemControlRegister; /* modem control register */    private byte modemStatusRegister; /* modem status register */    private byte scratchRegister; /* scratch register */    private boolean thrIPending; /* transmitter holding register interrupt */    private int irq; /* irq channel */    private int baseAddress; /* base I/O Port Address */    private InterruptController irqDevice;    public SerialPort(int portNumber)    {	ioportRegistered = false;	if (portNumber > 3 || portNumber < 0) {	    System.err.println(portNumber + " is a stupid number, assuming 0");	    portNumber = 0;	}	this.irq = SerialPort.irqLines[portNumber];	this.baseAddress = SerialPort.ioPorts[portNumber];	this.lineStatusRegister = UART_LSR_TEMT | UART_LSR_THRE;	this.interruptIORegister = UART_IIR_NO_INT;    }    public void dumpState(DataOutput output) throws IOException    {        output.writeShort(divider);        output.writeByte(receiverBufferRegister);        output.writeByte(interruptEnableRegister);        output.writeByte(interruptIORegister);        output.writeByte(lineControlRegister);        output.writeByte(modemControlRegister);        output.writeByte(lineStatusRegister);        output.writeByte(modemStatusRegister);        output.writeByte(scratchRegister);        output.writeBoolean(thrIPending);        output.writeInt(irq);        output.writeInt(baseAddress);    }    public void loadState(DataInput input) throws IOException    {        ioportRegistered = false;        divider = input.readShort();        receiverBufferRegister = input.readByte();        interruptEnableRegister = input.readByte();        interruptIORegister = input.readByte();        lineControlRegister = input.readByte();        modemControlRegister = input.readByte();        lineStatusRegister = input.readByte();        modemStatusRegister = input.readByte();        scratchRegister = input.readByte();        thrIPending = input.readBoolean();        irq = input.readInt();        baseAddress = input.readInt();    }    public int canReceive()    {	if (0 == (lineStatusRegister & UART_LSR_DR))	    return 1;	else	    return 0;    }    public void recieve(byte data)    {	receiverBufferRegister = data;	if (0 == data)	    lineStatusRegister = (byte)(lineStatusRegister | UART_LSR_DR);	else	    lineStatusRegister = (byte)(lineStatusRegister | UART_LSR_BI | UART_LSR_DR); 	this.updateIRQ();    }    private void updateIRQ()    {	if((0 != (lineStatusRegister & UART_LSR_DR)) && (0 != (interruptEnableRegister & UART_IER_RDI))) {	    interruptIORegister = UART_IIR_RDI;	} else if (thrIPending && (0 != (interruptEnableRegister & UART_IER_THRI))) {	    interruptIORegister = UART_IIR_THRI;	} else {	    interruptIORegister = UART_IIR_NO_INT;	}	if(interruptIORegister != UART_IIR_NO_INT) {	    irqDevice.setIRQ(irq, 1);	} else {	    irqDevice.setIRQ(irq, 0);	}    }    public void ioPortWriteByte(int address, int data)    {	this.ioportWrite(address, data);    }    public void ioPortWriteWord(int address, int data){}    public void ioPortWriteLong(int address, int data){}    public int ioPortReadByte(int address)    {	return this.ioportRead(address);    }    public int ioPortReadWord(int address)    {	return 0xffff;    }    public int ioPortReadLong(int address)    {	return (int)0xffffffff;    }    public int[] ioPortsRequested()    {	return new int[]{baseAddress, baseAddress + 1, baseAddress + 2, baseAddress + 3, baseAddress + 4, baseAddress + 5, baseAddress + 6, baseAddress + 7};    }    private void ioportWrite(int address, int data)    {	address &= 7;	switch(address) {	default:	case 0:	    if (0 != (lineControlRegister & UART_LCR_DLAB)) {		divider = (short)((divider & 0xff00) | data);	    } else {		thrIPending = false;		lineStatusRegister = (byte)(lineStatusRegister & ~UART_LSR_THRE);		this.updateIRQ();		System.out.print((char)(0xff & data));		//output data		thrIPending = true;		lineStatusRegister = (byte)(lineStatusRegister | UART_LSR_THRE | UART_LSR_TEMT);		this.updateIRQ();	    }	    break;	case 1:	    if (0 != (lineControlRegister & UART_LCR_DLAB)) {		divider = (short)((divider & 0x00ff) | (data << 8));	    } else {		interruptEnableRegister = (byte)(data & 0x0f);		if (0 != (lineStatusRegister & UART_LSR_THRE)) {		    thrIPending = true;		}		this.updateIRQ();	    }	    break;	case 2:	    break;	case 3:	    lineControlRegister = (byte)data;	    break;	case 4:	    modemControlRegister = (byte)(data & 0x1f);	    break;	case 5:	    break;	case 6:	    modemStatusRegister = (byte)data;	    break;	case 7:	    scratchRegister = (byte)data;	    break;	}    }    private int ioportRead(int address)    {	address &= 7;	int ret;	switch(address) {	default:	case 0:	    if(0 != (lineControlRegister & UART_LCR_DLAB)) {		return divider & 0xff;	    } else {		lineStatusRegister = (byte)(lineStatusRegister & ~(UART_LSR_DR | UART_LSR_BI));		ret = receiverBufferRegister;		this.updateIRQ();		return ret;	    }	case 1:	    if (0 != (lineControlRegister & UART_LCR_DLAB)) {		return (divider >>> 8) & 0xff;	    } else {		return interruptEnableRegister;	    }	case 2:	    ret = interruptIORegister;	    if ((ret & 0x7) == UART_IIR_THRI)		thrIPending = false;	    this.updateIRQ();	    return ret;	case 3:	    return lineControlRegister;	case 4:	    return modemControlRegister;	case 5:	    return lineStatusRegister;	case 6:	    if (0 != (modemControlRegister & UART_MCR_LOOP)) {		/* in loopback, the modem output pins are connected to the inputs */		ret = (modemControlRegister & 0x0c) << 4;		ret |= (modemControlRegister & 0x02) << 3;		ret |= (modemControlRegister & 0x01) << 5;		return ret;	    } else {		return modemStatusRegister;	    }	case 7:	    return scratchRegister;	}    }    private boolean ioportRegistered;    public void reset()    {	irqDevice = null;	ioportRegistered = false;	this.lineStatusRegister = UART_LSR_TEMT | UART_LSR_THRE;	this.interruptIORegister = UART_IIR_NO_INT;    }    public boolean initialised()    {	return ioportRegistered && (irqDevice != null);    }    public void timerCallback() {}    public boolean updated()    {	return ioportRegistered && irqDevice.updated();    }    public void updateComponent(HardwareComponent component)    {	if ((component instanceof IOPortHandler) && component.updated())         {	    ((IOPortHandler)component).registerIOPortCapable(this);	    ioportRegistered = true;	}    }    public void acceptComponent(HardwareComponent component)    {	if ((component instanceof InterruptController) &&	    component.initialised()) {	    irqDevice = (InterruptController)component;	}	if ((component instanceof IOPortHandler)	    && component.initialised()) {	    ((IOPortHandler)component).registerIOPortCapable(this);	    ioportRegistered = true;	}    }}

⌨️ 快捷键说明

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