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

📄 dmacontroller.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*    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.motherboard;import org.jpc.emulator.memory.*;import org.jpc.emulator.HardwareComponent;import java.io.*;public class DMAController implements IOPortCapable, HardwareComponent{    private static final int pagePortList0 = 0x1;    private static final int pagePortList1 = 0x2;    private static final int pagePortList2 = 0x3;    private static final int pagePortList3 = 0x7;    private static final int[] pagePortList = new int[]{pagePortList0, pagePortList1, pagePortList2, pagePortList3};    private static final int CMD_MEMORY_TO_MEMORY = 0x01;    private static final int CMD_FIXED_ADDRESS = 0x02;    private static final int CMD_BLOCK_CONTROLLER = 0x04;    private static final int CMD_COMPRESSED_TIME = 0x08;    private static final int CMD_CYCLIC_PRIORITY = 0x10;    private static final int CMD_EXTENDED_WRITE = 0x20;    private static final int CMD_LOW_DREQ = 0x40;    private static final int CMD_LOW_DACK = 0x80;    private static final int CMD_NOT_SUPPORTED = CMD_MEMORY_TO_MEMORY | CMD_FIXED_ADDRESS | CMD_COMPRESSED_TIME | CMD_CYCLIC_PRIORITY | CMD_EXTENDED_WRITE | CMD_LOW_DREQ | CMD_LOW_DACK;    private int status;    private int command;    private int mask;    private boolean flipFlop;    private int dShift;    private int iobase, pageBase, pageHBase;    private int controllerNumber;    private PhysicalAddressSpace memory;//     private DMABackgroundTask dmaTask;//     private static final int DMA_TRANSFER_TASK_PERIOD_MAX = 200;//     private static final int DMA_TRANSFER_TASK_PERIOD_MIN = 1;    static class DMARegister    {	public static final int ADDRESS = 0;	public static final int COUNT = 1;	public int nowAddress;	public int nowCount;	public short baseAddress;	public short baseCount;	public int mode;	public byte page, pageh, dack, eop;	public DMATransferCapable transferDevice;	public DMARegister()	{	}        public void dumpState(DataOutput output) throws IOException        {            output.writeInt(nowAddress);            output.writeInt(nowCount);            output.writeShort(baseAddress);            output.writeShort(baseCount);            output.writeInt(mode);            output.writeByte(page);            output.writeByte(pageh);            output.writeByte(dack);            output.writeByte(eop);            //tactfully ignore transferDevice        }        public void loadState(DataInput input) throws IOException        {            nowAddress = input.readInt();            nowCount = input.readInt();            baseAddress = input.readShort();            baseCount = input.readShort();            mode = input.readInt();            page = input.readByte();            pageh = input.readByte();            dack = input.readByte();            eop = input.readByte();            //tactfully ignore transferDevice        }	public void reset()	{	    transferDevice = null;	    nowAddress = nowCount = mode = 0;	    baseAddress = baseCount = 0;	    page = pageh = dack = eop = 0;	}    }    private DMARegister[] dmaRegs;    public DMAController(boolean highPageEnable, boolean zeroth)    {	ioportRegistered = false;	this.dShift = zeroth ? 0 : 1;	this.iobase = zeroth ? 0x00 : 0xc0;	this.pageBase = zeroth ? 0x80 : 0x88;	this.pageHBase = highPageEnable ? (zeroth ? 0x480 : 0x488) : -1;	this.controllerNumber = zeroth ? 0 : 1;	dmaRegs = new DMARegister[4];	for (int i = 0; i < 4; i++)	    dmaRegs[i] = new DMARegister();	this.reset();// 	dmaTask = new DMABackgroundTask();// 	dmaTask.start();    }    public void dumpState(DataOutput output) throws IOException    {        output.writeInt(status);        output.writeInt(command);        output.writeInt(mask);        output.writeBoolean(flipFlop);        output.writeInt(dShift);        output.writeInt(iobase);        output.writeInt(pageBase);        output.writeInt(pageHBase);        output.writeInt(controllerNumber);        output.writeInt(dmaRegs.length);        for (int i=0; i < dmaRegs.length; i++)            dmaRegs[i].dumpState(output);    }    public void loadState(DataInput input) throws IOException    {        ioportRegistered = false;        status = input.readInt();        command = input.readInt();        mask = input.readInt();        flipFlop = input.readBoolean();        dShift = input.readInt();        iobase = input.readInt();        pageBase = input.readInt();        pageHBase = input.readInt();        controllerNumber = input.readInt();        int len = input.readInt();        dmaRegs = new DMARegister[len];        for (int i=0; i < dmaRegs.length; i++)        {            dmaRegs[i] = new DMARegister();            dmaRegs[i].loadState(input);        }    }    public boolean isFirst()    {	return (this.dShift == 0);    }    public void reset()    {	for (int i = 0; i < dmaRegs.length; i++)	    dmaRegs[i].reset();		this.writeController(0x0d << this.dShift, 0);	       	memory = null;	ioportRegistered = false;    }        private void writeChannel(int portNumber, int data)    {	int port = (portNumber >>> dShift) & 0x0f;	int channelNumber = port >>> 1;	DMARegister r = dmaRegs[channelNumber];	if (getFlipFlop()) {	    if ((port & 1) == DMARegister.ADDRESS)		r.baseAddress = (short)((r.baseAddress & 0xff) | ((data << 8) & 0xff00));	    else		r.baseCount = (short)((r.baseCount & 0xff) | ((data << 8) & 0xff00));	    initChannel(channelNumber);	} else {	    if ((port & 1) == DMARegister.ADDRESS)		r.baseAddress = (short)((r.baseAddress & 0xff00) | (data & 0xff));	    else		r.baseCount = (short)((r.baseCount & 0xff00) | (data & 0xff));	}    }    private void writeController(int portNumber, int data)    {	int port = (portNumber >>> this.dShift) & 0x0f;	switch (port) {	case 0x08: /* command */	    if ((data != 0) && ((data & CMD_NOT_SUPPORTED) != 0))		break;	    command = data;	    break;	case 0x09:	    int channelNumber = data & 3;	    if ((data  & 4) != 0) {		status |= 1 << (channelNumber + 4);	    } else {		status &= ~(1 << (channelNumber + 4));	    }	    status &= ~(1 << channelNumber);	    runTransfers();	    break;	case 0x0a: /* single mask */	    if ((data & 0x4) != 0) {		mask |= 1 << (data & 3);	    } else {		mask &= ~(1 << (data & 3));		runTransfers();	    }	    break;	case 0x0b: /* mode */	    channelNumber = data & 3;	    dmaRegs[channelNumber].mode = data;	    break;	case 0x0c: /* clear flipFlop */	    flipFlop = false;	    break;	case 0x0d: /* reset */	    flipFlop = false;	    mask = ~0;	    status = 0;	    command = 0;	    break;	case 0x0e: /* clear mask for all channels */	    mask = 0;	    runTransfers();	    break;	case 0x0f: /* write mask for all channels */	    mask = data;	    runTransfers();	    break;	default:	    break;	}    }    private static final int[] channels = new int[]{-1, 2, 3, 1, 						      -1, -1, -1, 0};    private void writePage(int portNumber, int data)    {	int channelNumber = channels[portNumber & 7];	if (-1 == channelNumber) {	    return;	}	dmaRegs[channelNumber].page = (byte)data;    }    private void writePageH(int portNumber, int data)    {	int channelNumber = channels[portNumber & 7];	if (-1 == channelNumber) {	    return;	}	dmaRegs[channelNumber].pageh = (byte)data;    }    private int readChannel(int portNumber)    {	int port = (portNumber >>> dShift) & 0x0f;	int channelNumber = port >>> 1;	int registerNumber = port & 1;	DMARegister r = dmaRegs[channelNumber];	int direction = ((r.mode & 0x20) == 0) ? 1 : -1;	boolean flipflop = getFlipFlop();	int val;	if (registerNumber != 0) {	    val = ((0xffff & r.baseCount) << dShift)		- r.nowCount;	} else {	    val = r.nowAddress + r.nowCount * direction;	}	return (val >>> (dShift + (flipflop ? 0x8 : 0x0))) & 0xff;    }    private int readController(int portNumber)    {	int val;	int port = (portNumber >>> dShift) & 0x0f;	switch (port) {	case 0x08:	    val = status;	    status &= 0xf0;	    break;	case 0x0f:

⌨️ 快捷键说明

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